
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
  <head>
    <meta charset="utf-8" />
    <title>6. 表达式 &#8212; Python 3.7.8 文档</title>
    <link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    
    <script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/underscore.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <script type="text/javascript" src="../_static/language_data.js"></script>
    <script type="text/javascript" src="../_static/translations.js"></script>
    
    <script type="text/javascript" src="../_static/sidebar.js"></script>
    
    <link rel="search" type="application/opensearchdescription+xml"
          title="在 Python 3.7.8 文档 中搜索"
          href="../_static/opensearch.xml"/>
    <link rel="author" title="关于这些文档" href="../about.html" />
    <link rel="index" title="索引" href="../genindex.html" />
    <link rel="search" title="搜索" href="../search.html" />
    <link rel="copyright" title="版权所有" href="../copyright.html" />
    <link rel="next" title="7. 简单语句" href="simple_stmts.html" />
    <link rel="prev" title="5. 导入系统" href="import.html" />
    <link rel="shortcut icon" type="image/png" href="../_static/py.png" />
    <link rel="canonical" href="https://docs.python.org/3/reference/expressions.html" />
    
    <script type="text/javascript" src="../_static/copybutton.js"></script>
    
    
    
    
    <style>
      @media only screen {
        table.full-width-table {
            width: 100%;
        }
      }
    </style>
 

  </head><body>
  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             accesskey="I">索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="simple_stmts.html" title="7. 简单语句"
             accesskey="N">下一页</a> |</li>
        <li class="right" >
          <a href="import.html" title="5. 导入系统"
             accesskey="P">上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <a href="../index.html">3.7.8 Documentation</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python语言参考</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>    

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <div class="section" id="expressions">
<span id="id1"></span><h1><span class="section-number">6. </span>表达式<a class="headerlink" href="#expressions" title="永久链接至标题">¶</a></h1>
<p id="index-0">本章将解释 Python 中组成表达式的各种元素的的含义。</p>
<p><strong>语法注释:</strong> 在本章和后续章节中，会使用扩展 BNF 标注来描述语法而不是词法分析。 当（某种替代的）语法规则具有如下形式</p>
<pre>
<strong id="grammar-token-name">name</strong> ::=  <code class="xref docutils literal notranslate"><span class="pre">othername</span></code>
</pre>
<p>并且没有给出语义，则这种形式的 <code class="docutils literal notranslate"><span class="pre">name</span></code> 在语法上与 <code class="docutils literal notranslate"><span class="pre">othername</span></code> 相同。</p>
<div class="section" id="arithmetic-conversions">
<span id="conversions"></span><h2><span class="section-number">6.1. </span>算术转换<a class="headerlink" href="#arithmetic-conversions" title="永久链接至标题">¶</a></h2>
<p id="index-1">当对下述某个算术运算符的描述中使用了“数值参数被转换为普通类型”这样的说法，这意味着内置类型的运算符实现采用了如下运作方式:</p>
<ul class="simple">
<li><p>如果任一参数为复数，另一参数会被转换为复数；</p></li>
<li><p>否则，如果任一参数为浮点数，另一参数会被转换为浮点数；</p></li>
<li><p>否则，两者应该都为整数，不需要进行转换。</p></li>
</ul>
<p>某些附加规则会作用于特定运算符（例如，字符串作为 '%' 运算符的左运算参数）。 扩展必须定义它们自己的转换行为。</p>
</div>
<div class="section" id="atoms">
<span id="id2"></span><h2><span class="section-number">6.2. </span>原子<a class="headerlink" href="#atoms" title="永久链接至标题">¶</a></h2>
<p id="index-2">“原子”指表达式的最基本构成元素。 最简单的原子是标识符和字面值。 以圆括号、方括号或花括号包括的形式在语法上也被归类为原子。 原子的句法为:</p>
<pre>
<strong id="grammar-token-atom">atom     </strong> ::=  <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a> | <a class="reference internal" href="#grammar-token-literal"><code class="xref docutils literal notranslate"><span class="pre">literal</span></code></a> | <a class="reference internal" href="#grammar-token-enclosure"><code class="xref docutils literal notranslate"><span class="pre">enclosure</span></code></a>
<strong id="grammar-token-enclosure">enclosure</strong> ::=  <a class="reference internal" href="#grammar-token-parenth-form"><code class="xref docutils literal notranslate"><span class="pre">parenth_form</span></code></a> | <a class="reference internal" href="#grammar-token-list-display"><code class="xref docutils literal notranslate"><span class="pre">list_display</span></code></a> | <a class="reference internal" href="#grammar-token-dict-display"><code class="xref docutils literal notranslate"><span class="pre">dict_display</span></code></a> | <a class="reference internal" href="#grammar-token-set-display"><code class="xref docutils literal notranslate"><span class="pre">set_display</span></code></a>
               | <a class="reference internal" href="#grammar-token-generator-expression"><code class="xref docutils literal notranslate"><span class="pre">generator_expression</span></code></a> | <a class="reference internal" href="#grammar-token-yield-atom"><code class="xref docutils literal notranslate"><span class="pre">yield_atom</span></code></a>
</pre>
<div class="section" id="atom-identifiers">
<span id="identifiers-names"></span><h3><span class="section-number">6.2.1. </span>标识符（名称）<a class="headerlink" href="#atom-identifiers" title="永久链接至标题">¶</a></h3>
<p id="index-3">作为原子出现的标识符叫做名称。 请参看 <a class="reference internal" href="lexical_analysis.html#identifiers"><span class="std std-ref">标识符和关键字</span></a> 一节了解其词法定义，以及 <a class="reference internal" href="executionmodel.html#naming"><span class="std std-ref">命名与绑定</span></a> 获取有关命名与绑定的文档。</p>
<p id="index-4">当名称被绑定到一个对象时，对该原子求值将返回相应对象。 当名称未被绑定时，尝试对其求值将引发 <a class="reference internal" href="../library/exceptions.html#NameError" title="NameError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">NameError</span></code></a> 异常。</p>
<p id="index-5"><strong>私有名称转换:</strong> 当以文本形式出现在类定义中的一个标识符以两个或更多下划线开头并且不以两个或更多下划线结尾，它会被视为该类的 <em class="dfn">私有名称</em>。 私有名称会在为其生成代码之前被转换为一种更长的形式。 转换时会插入类名，移除打头的下划线再在名称前增加一个下划线。 例如，出现在一个名为 <code class="docutils literal notranslate"><span class="pre">Ham</span></code> 的类中的标识符 <code class="docutils literal notranslate"><span class="pre">__spam</span></code> 会被转换为 <code class="docutils literal notranslate"><span class="pre">_Ham__spam</span></code>。 这种转换独立于标识符所使用的相关句法。 如果转换后的名称太长（超过 255 个字符），可能发生由具体实现定义的截断。 如果类名仅由下划线组成，则不会进行转换。</p>
</div>
<div class="section" id="literals">
<span id="atom-literals"></span><h3><span class="section-number">6.2.2. </span>字面值<a class="headerlink" href="#literals" title="永久链接至标题">¶</a></h3>
<p id="index-6">Python 支持字符串和字节串字面值，以及几种数字字面值:</p>
<pre>
<strong id="grammar-token-literal">literal</strong> ::=  <a class="reference internal" href="lexical_analysis.html#grammar-token-stringliteral"><code class="xref docutils literal notranslate"><span class="pre">stringliteral</span></code></a> | <a class="reference internal" href="lexical_analysis.html#grammar-token-bytesliteral"><code class="xref docutils literal notranslate"><span class="pre">bytesliteral</span></code></a>
             | <a class="reference internal" href="lexical_analysis.html#grammar-token-integer"><code class="xref docutils literal notranslate"><span class="pre">integer</span></code></a> | <a class="reference internal" href="lexical_analysis.html#grammar-token-floatnumber"><code class="xref docutils literal notranslate"><span class="pre">floatnumber</span></code></a> | <a class="reference internal" href="lexical_analysis.html#grammar-token-imagnumber"><code class="xref docutils literal notranslate"><span class="pre">imagnumber</span></code></a>
</pre>
<p>对字面值求值将返回一个该值所对应类型的对象（字符串、字节串、整数、浮点数、复数）。 对于浮点数和虚数（复数）的情况，该值可能为近似值。 详情参见 <a class="reference internal" href="lexical_analysis.html#literals"><span class="std std-ref">字面值</span></a>。</p>
<p id="index-7">所有字面值都对应与不可变数据类型，因此对象标识的重要性不如其实际值。 多次对具有相同值的字面值求值（不论是发生在程序文本的相同位置还是不同位置）可能得到相同对象或是具有相同值的不同对象。</p>
</div>
<div class="section" id="parenthesized-forms">
<span id="parenthesized"></span><h3><span class="section-number">6.2.3. </span>带圆括号的形式<a class="headerlink" href="#parenthesized-forms" title="永久链接至标题">¶</a></h3>
<p id="index-8">带圆括号的形式是包含在圆括号中的可选表达式列表。</p>
<pre>
<strong id="grammar-token-parenth-form">parenth_form</strong> ::=  &quot;(&quot; [<a class="reference internal" href="#grammar-token-starred-expression"><code class="xref docutils literal notranslate"><span class="pre">starred_expression</span></code></a>] &quot;)&quot;
</pre>
<p>带圆括号的表达式列表将返回该表达式列表所产生的任何东西：如果该列表包含至少一个逗号，它会产生一个元组；否则，它会产生该表达式列表所对应的单一表达式。</p>
<p id="index-9">一对内容为空的圆括号将产生一个空的元组对象。 由于元组是不可变对象，因此适用与字面值相同的规则（即两次出现的空元组产生的对象可能相同也可能不同）。</p>
<p id="index-10">请注意元组并不是由圆括号构建，实际起作用的是逗号操作符。 例外情况是空元组，这时圆括号 <em>才是</em> 必须的 --- 允许在表达式中使用不带圆括号的 &quot;空&quot; 会导致歧义，并会造成常见输入错误无法被捕获。</p>
</div>
<div class="section" id="displays-for-lists-sets-and-dictionaries">
<span id="comprehensions"></span><h3><span class="section-number">6.2.4. </span>列表、集合与字典的显示<a class="headerlink" href="#displays-for-lists-sets-and-dictionaries" title="永久链接至标题">¶</a></h3>
<p>为了构建列表、集合或字典，Python 提供了名为“显示”的特殊句法，每个类型各有两种形式:</p>
<ul class="simple">
<li><p>第一种是显式地列出容器内容</p></li>
<li><p>第二种是通过一组循环和筛选指令计算出来，称为 <em class="dfn">推导式</em>。</p></li>
</ul>
<p id="index-11">推导式的常用句法元素为:</p>
<pre>
<strong id="grammar-token-comprehension">comprehension</strong> ::=  <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> <a class="reference internal" href="#grammar-token-comp-for"><code class="xref docutils literal notranslate"><span class="pre">comp_for</span></code></a>
<strong id="grammar-token-comp-for">comp_for     </strong> ::=  [&quot;async&quot;] &quot;for&quot; <a class="reference internal" href="simple_stmts.html#grammar-token-target-list"><code class="xref docutils literal notranslate"><span class="pre">target_list</span></code></a> &quot;in&quot; <a class="reference internal" href="#grammar-token-or-test"><code class="xref docutils literal notranslate"><span class="pre">or_test</span></code></a> [<a class="reference internal" href="#grammar-token-comp-iter"><code class="xref docutils literal notranslate"><span class="pre">comp_iter</span></code></a>]
<strong id="grammar-token-comp-iter">comp_iter    </strong> ::=  <a class="reference internal" href="#grammar-token-comp-for"><code class="xref docutils literal notranslate"><span class="pre">comp_for</span></code></a> | <a class="reference internal" href="#grammar-token-comp-if"><code class="xref docutils literal notranslate"><span class="pre">comp_if</span></code></a>
<strong id="grammar-token-comp-if">comp_if      </strong> ::=  &quot;if&quot; <a class="reference internal" href="#grammar-token-expression-nocond"><code class="xref docutils literal notranslate"><span class="pre">expression_nocond</span></code></a> [<a class="reference internal" href="#grammar-token-comp-iter"><code class="xref docutils literal notranslate"><span class="pre">comp_iter</span></code></a>]
</pre>
<p>推导式的结构是一个单独表达式后面加至少一个 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 子句以及零个或更多个 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 或 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code> 子句。 在这种情况下，新容器的元素产生方式是将每个 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 或 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code> 子句视为一个代码块，按从左至右的顺序嵌套，然后每次到达最内层代码块时就对表达式进行求值以产生一个元素。</p>
<p>不过，除了最左边 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 子句中的可迭代表达式，推导式是在另一个隐式嵌套的作用域内执行的。 这能确保赋给目标列表的名称不会“泄露”到外层的作用域。</p>
<p>最左边 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 子句中的可迭代表达式会直接在外层作用域中被求值，然后作为一个参数被传给隐式嵌套的作用域。 后续的 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 子句以及最左侧 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 子句中的任何筛选条件不能在外层作用域中被求值，因为它们可能依赖于从最左侧可迭代对象中获得的值。 例如: <code class="docutils literal notranslate"><span class="pre">[x*y</span> <span class="pre">for</span> <span class="pre">x</span> <span class="pre">in</span> <span class="pre">range(10)</span> <span class="pre">for</span> <span class="pre">y</span> <span class="pre">in</span> <span class="pre">range(x,</span> <span class="pre">x+10)]</span></code>.</p>
<p>为了确保推导式得出的结果总是一个类型正确的容器，在隐式嵌套的作用域内禁止使用 <code class="docutils literal notranslate"><span class="pre">yield</span></code> 和 <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> 表达式 (在 Python 3.7 中，这样的表达式会在编译时引发 <a class="reference internal" href="../library/exceptions.html#DeprecationWarning" title="DeprecationWarning"><code class="xref py py-exc docutils literal notranslate"><span class="pre">DeprecationWarning</span></code></a>，在 Python 3.8+ 中它们将引发 <a class="reference internal" href="../library/exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxError</span></code></a>)。</p>
<p id="index-12">从 Python 3.6 开始，在 <a class="reference internal" href="compound_stmts.html#async-def"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">def</span></code></a> 函数中可以使用 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code> 子句来迭代 <a class="reference internal" href="../glossary.html#term-asynchronous-iterator"><span class="xref std std-term">asynchronous iterator</span></a>。 在 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">def</span></code> 函数中构建推导式可以通过在打头的表达式后加上 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 或 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code> 子句，也可能包含额外的 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 或 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code> 子句，还可能使用 <a class="reference internal" href="#await"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">await</span></code></a> 表达式。 如果一个推导式包含 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code> 子句或者 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">await</span></code> 表达式，则被称为 <em class="dfn">异步推导式</em>。 异步推导式可以暂停执行它所在的协程函数。 另请参阅 <span class="target" id="index-103"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0530"><strong>PEP 530</strong></a>。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.6 新版功能: </span>引入了异步推导式。</p>
</div>
<div class="deprecated">
<p><span class="versionmodified deprecated">3.7 版后已移除: </span><code class="docutils literal notranslate"><span class="pre">yield</span></code> and <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> 在隐式嵌套的作用域内已弃用。</p>
</div>
</div>
<div class="section" id="list-displays">
<span id="lists"></span><h3><span class="section-number">6.2.5. </span>列表显示<a class="headerlink" href="#list-displays" title="永久链接至标题">¶</a></h3>
<p id="index-14">列表显示是一个用方括号括起来的可能为空的表达式系列:</p>
<pre>
<strong id="grammar-token-list-display">list_display</strong> ::=  &quot;[&quot; [<a class="reference internal" href="#grammar-token-starred-list"><code class="xref docutils literal notranslate"><span class="pre">starred_list</span></code></a> | <a class="reference internal" href="#grammar-token-comprehension"><code class="xref docutils literal notranslate"><span class="pre">comprehension</span></code></a>] &quot;]&quot;
</pre>
<p>列表显示会产生一个新的列表对象，其内容通过一系列表达式或一个推导式来指定。 当提供由逗号分隔的一系列表达式时，其元素会从左至右被求值并按此顺序放入列表对象。 当提供一个推导式时，列表会根据推导式所产生的结果元素进行构建。</p>
</div>
<div class="section" id="set-displays">
<span id="set"></span><h3><span class="section-number">6.2.6. </span>集合显示<a class="headerlink" href="#set-displays" title="永久链接至标题">¶</a></h3>
<p id="index-15">集合显示是用花括号标明的，与字典显示的区别在于没有冒号分隔的键和值:</p>
<pre>
<strong id="grammar-token-set-display">set_display</strong> ::=  &quot;{&quot; (<a class="reference internal" href="#grammar-token-starred-list"><code class="xref docutils literal notranslate"><span class="pre">starred_list</span></code></a> | <a class="reference internal" href="#grammar-token-comprehension"><code class="xref docutils literal notranslate"><span class="pre">comprehension</span></code></a>) &quot;}&quot;
</pre>
<p>集合显示会产生一个新的可变集合对象，其内容通过一系列表达式或一个推导式来指定。 当提供由逗号分隔的一系列表达式时，其元素会从左至右被求值并加入到集合对象。 当提供一个推导式时，集合会根据推导式所产生的结果元素进行构建。</p>
<p>空集合不能用 <code class="docutils literal notranslate"><span class="pre">{}</span></code> 来构建；该字面值所构建的是一个空字典。</p>
</div>
<div class="section" id="dictionary-displays">
<span id="dict"></span><h3><span class="section-number">6.2.7. </span>字典显示<a class="headerlink" href="#dictionary-displays" title="永久链接至标题">¶</a></h3>
<p id="index-16">字典显示是一个用花括号括起来的可能为空的键/数据对系列:</p>
<pre>
<strong id="grammar-token-dict-display">dict_display      </strong> ::=  &quot;{&quot; [<a class="reference internal" href="#grammar-token-key-datum-list"><code class="xref docutils literal notranslate"><span class="pre">key_datum_list</span></code></a> | <a class="reference internal" href="#grammar-token-dict-comprehension"><code class="xref docutils literal notranslate"><span class="pre">dict_comprehension</span></code></a>] &quot;}&quot;
<strong id="grammar-token-key-datum-list">key_datum_list    </strong> ::=  <a class="reference internal" href="#grammar-token-key-datum"><code class="xref docutils literal notranslate"><span class="pre">key_datum</span></code></a> (&quot;,&quot; <a class="reference internal" href="#grammar-token-key-datum"><code class="xref docutils literal notranslate"><span class="pre">key_datum</span></code></a>)* [&quot;,&quot;]
<strong id="grammar-token-key-datum">key_datum         </strong> ::=  <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> &quot;:&quot; <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> | &quot;**&quot; <a class="reference internal" href="#grammar-token-or-expr"><code class="xref docutils literal notranslate"><span class="pre">or_expr</span></code></a>
<strong id="grammar-token-dict-comprehension">dict_comprehension</strong> ::=  <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> &quot;:&quot; <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> <a class="reference internal" href="#grammar-token-comp-for"><code class="xref docutils literal notranslate"><span class="pre">comp_for</span></code></a>
</pre>
<p>字典显示会产生一个新的字典对象。</p>
<p>如果给出一个由逗号分隔的键/数据对序列，它们会从左至右被求值以定义字典的条目：每个键对象会被用作在字典中存放相应数据的键。 这意味着你可以在键/数据对序列中多次指定相同的键，最终字典的值将由最后一次给出的键决定。</p>
<p id="index-17">双星号 <code class="docutils literal notranslate"><span class="pre">**</span></code> 表示 <em class="dfn">字典拆包</em>。 它的操作数必须是一个 <a class="reference internal" href="../glossary.html#term-mapping"><span class="xref std std-term">mapping</span></a>。 每个映射项被会加入新的字典。 后续的值会替代先前的键/数据对和先前的字典拆包所设置的值。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.5 新版功能: </span>拆包到字典显示，最初由 <span class="target" id="index-104"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0448"><strong>PEP 448</strong></a> 提出。</p>
</div>
<p>字典推导式与列表和集合推导式有所不同，它需要以冒号分隔的两个表达式，后面带上标准的 &quot;for&quot; 和 &quot;if&quot; 子句。 当推导式被执行时，作为结果的键和值元素会按它们的产生顺序被加入新的字典。</p>
<p id="index-19">对键取值类型的限制已列在之前的 <a class="reference internal" href="datamodel.html#types"><span class="std std-ref">标准类型层级结构</span></a> 一节中。 (总的说来，键的类型应该为 <a class="reference internal" href="../glossary.html#term-hashable"><span class="xref std std-term">hashable</span></a>，这就把所有可变对象都排除在外。) 重复键之间的冲突不会被检测；指定键所保存的最后一个数据 (即在显示中排最右边的文本) 为最终有效数据。</p>
</div>
<div class="section" id="generator-expressions">
<span id="genexpr"></span><h3><span class="section-number">6.2.8. </span>生成器表达式<a class="headerlink" href="#generator-expressions" title="永久链接至标题">¶</a></h3>
<p id="index-20">生成器表达式是用圆括号括起来的紧凑形式生成器标注。</p>
<pre>
<strong id="grammar-token-generator-expression">generator_expression</strong> ::=  &quot;(&quot; <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> <a class="reference internal" href="#grammar-token-comp-for"><code class="xref docutils literal notranslate"><span class="pre">comp_for</span></code></a> &quot;)&quot;
</pre>
<p>生成器表达式会产生一个新的生成器对象。 其句法与推导式相同，区别在于它是用圆括号而不是用方括号或花括号括起来的。</p>
<p>在生成器表达式中使用的变量会在为生成器对象调用 <a class="reference internal" href="#generator.__next__" title="generator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> 方法的时候以惰性方式被求值（即与普通生成器相同的方式）。 但是，最左侧 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 子句内的可迭代对象是会被立即求值的，因此它所造成的错误会在生成器表达式被定义时被检测到，而不是在获取第一个值时才出错。 后续的 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 子句以及最左侧 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 子句内的任何筛选条件无法在外层作用域内被求值，因为它们可能会依赖于从最左侧可迭代对象获取的值。 例如: <code class="docutils literal notranslate"><span class="pre">(x*y</span> <span class="pre">for</span> <span class="pre">x</span> <span class="pre">in</span> <span class="pre">range(10)</span> <span class="pre">for</span> <span class="pre">y</span> <span class="pre">in</span> <span class="pre">range(x,</span> <span class="pre">x+10))</span></code>.</p>
<p>圆括号在只附带一个参数的调用中可以被省略。 详情参见 <a class="reference internal" href="#calls"><span class="std std-ref">调用</span></a> 一节。</p>
<p>为避免干扰到生成器表达式本身预期的操作，<code class="docutils literal notranslate"><span class="pre">yield</span></code> 和 <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> 表达式禁止在隐式定义的生成器中使用 (在 Python 3.7 中，这种表达式会在编译时引发 <a class="reference internal" href="../library/exceptions.html#DeprecationWarning" title="DeprecationWarning"><code class="xref py py-exc docutils literal notranslate"><span class="pre">DeprecationWarning</span></code></a>，在 Python 3.8+ 中它们将引发 <a class="reference internal" href="../library/exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxError</span></code></a>)。</p>
<p>如果生成器表达式包含 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code> 子句或 <a class="reference internal" href="#await"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">await</span></code></a> 表达式，则称为 <em class="dfn">异步生成器表达式</em>。 异步生成器表达式会返回一个新的异步生成器对象，此对象属于异步迭代器 (参见 <a class="reference internal" href="datamodel.html#async-iterators"><span class="std std-ref">异步迭代器</span></a>)。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.6 新版功能: </span>引入了异步生成器表达式。</p>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.7 版更改: </span>在 Python 3.7 之前，异步生成器表达式只能在 <a class="reference internal" href="compound_stmts.html#async-def"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">def</span></code></a> 协和中出现。 从 3.7 开始，任何函数都可以使用异步生成器表达式。</p>
</div>
<div class="deprecated">
<p><span class="versionmodified deprecated">3.7 版后已移除: </span><code class="docutils literal notranslate"><span class="pre">yield</span></code> and <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> 在隐式嵌套的作用域内已弃用。</p>
</div>
</div>
<div class="section" id="yield-expressions">
<span id="yieldexpr"></span><h3><span class="section-number">6.2.9. </span>yield 表达式<a class="headerlink" href="#yield-expressions" title="永久链接至标题">¶</a></h3>
<pre id="index-21">
<strong id="grammar-token-yield-atom">yield_atom      </strong> ::=  &quot;(&quot; <a class="reference internal" href="#grammar-token-yield-expression"><code class="xref docutils literal notranslate"><span class="pre">yield_expression</span></code></a> &quot;)&quot;
<strong id="grammar-token-yield-expression">yield_expression</strong> ::=  &quot;yield&quot; [<a class="reference internal" href="#grammar-token-expression-list"><code class="xref docutils literal notranslate"><span class="pre">expression_list</span></code></a> | &quot;from&quot; <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>]
</pre>
<p>yield 表达式在定义 <a class="reference internal" href="../glossary.html#term-generator"><span class="xref std std-term">generator</span></a> 函数或是 <a class="reference internal" href="../glossary.html#term-asynchronous-generator"><span class="xref std std-term">asynchronous generator</span></a> 的时候才会用到。 因此只能在函数定义的内部使用yield表达式。 在一个函数体内使用 yield 表达式会使这个函数变成一个生成器，并且在一个 <a class="reference internal" href="compound_stmts.html#async-def"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">def</span></code></a> 定义的函数体内使用 yield 表达式会让协程函数变成异步的生成器。 比如说:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">gen</span><span class="p">():</span>  <span class="c1"># defines a generator function</span>
    <span class="k">yield</span> <span class="mi">123</span>

<span class="k">async</span> <span class="k">def</span> <span class="nf">agen</span><span class="p">():</span> <span class="c1"># defines an asynchronous generator function</span>
    <span class="k">yield</span> <span class="mi">123</span>
</pre></div>
</div>
<p>由于它们会对外层作用域造成附带影响，<code class="docutils literal notranslate"><span class="pre">yield</span></code> 表达式不被允许作为用于实现推导式和生成器表达式的隐式定义作用域的一部分 (在 Python 3.7 中，此类表达式会在编译时引发 <a class="reference internal" href="../library/exceptions.html#DeprecationWarning" title="DeprecationWarning"><code class="xref py py-exc docutils literal notranslate"><span class="pre">DeprecationWarning</span></code></a>，在 Python 3.8+ 中它们将引发 <a class="reference internal" href="../library/exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxError</span></code></a>)。</p>
<div class="deprecated">
<p><span class="versionmodified deprecated">3.7 版后已移除: </span>yield 表达式在用于实现推导式和生成器表达式的隐式嵌套作用域中已弃用。</p>
</div>
<p>下面是对生成器函数的描述，异步生成器函数会在 <a class="reference internal" href="#asynchronous-generator-functions"><span class="std std-ref">异步生成器函数</span></a> 一节中单独介绍。</p>
<p>当一个生成器函数被调用的时候，它返回一个迭代器，称为生成器。然后这个生成器来控制生成器函数的执行。当这个生成器的某一个方法被调用的时候，生成器函数开始执行。这时会一直执行到第一个 yield 表达式，在此执行再次被挂起，给生成器的调用者返回  <a class="reference internal" href="#grammar-token-expression-list"><code class="xref std std-token docutils literal notranslate"><span class="pre">expression_list</span></code></a> 的值。挂起后，我们说所有局部状态都被保留下来，包括局部变量的当前绑定，指令指针，内部求值栈和任何异常处理的状态。通过调用生成器的某一个方法，生成器函数继续执行。此时函数的运行就和 yield 表达式只是一个外部函数调用的情况完全一致。恢复后 yield 表达式的值取决于调用的哪个方法来恢复执行。 如果用的是 <a class="reference internal" href="#generator.__next__" title="generator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> (通常通过语言内置的 <a class="reference internal" href="compound_stmts.html#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a> 或是 <a class="reference internal" href="../library/functions.html#next" title="next"><code class="xref py py-func docutils literal notranslate"><span class="pre">next()</span></code></a> 来调用) 那么结果就是 <a class="reference internal" href="../library/constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>.  否则，如果用 <a class="reference internal" href="#generator.send" title="generator.send"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send()</span></code></a>, 那么结果就是传递给send方法的值。</p>
<p id="index-22">所有这些使生成器函数与协程非常相似；它们 yield 多次，它们具有多个入口点，并且它们的执行可以被挂起。唯一的区别是生成器函数不能控制在它在 yield 后交给哪里继续执行；控制权总是转移到生成器的调用者。</p>
<p>在 <a class="reference internal" href="compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 结构中的任何位置都允许yield表达式。如果生成器在(因为引用计数到零或是因为被垃圾回收)销毁之前没有恢复执行，将调用生成器-迭代器的 <a class="reference internal" href="#generator.close" title="generator.close"><code class="xref py py-meth docutils literal notranslate"><span class="pre">close()</span></code></a> 方法. close 方法允许任何挂起的 <a class="reference internal" href="compound_stmts.html#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子句执行。</p>
<p id="index-23">当使用 <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span> <span class="pre">&lt;expr&gt;</span></code> 时，它会将所提供的表达式视为一个子迭代器。 这个子迭代器产生的所有值都直接被传递给当前生成器方法的调用者。 通过 <a class="reference internal" href="#generator.send" title="generator.send"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send()</span></code></a> 传入的任何值以及通过 <a class="reference internal" href="#generator.throw" title="generator.throw"><code class="xref py py-meth docutils literal notranslate"><span class="pre">throw()</span></code></a> 传入的任何异常如果有适当的方法则会被传给下层迭代器。 如果不是这种情况，那么 <a class="reference internal" href="#generator.send" title="generator.send"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send()</span></code></a> 将引发 <a class="reference internal" href="../library/exceptions.html#AttributeError" title="AttributeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">AttributeError</span></code></a> 或 <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a>，而 <a class="reference internal" href="#generator.throw" title="generator.throw"><code class="xref py py-meth docutils literal notranslate"><span class="pre">throw()</span></code></a> 将立即引发所传入的异常。</p>
<p>当下层迭代器完成时，被引发的 <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> 实例的 <code class="xref py py-attr docutils literal notranslate"><span class="pre">value</span></code> 属性会成为 yield 表达式的值。 它可以在引发 <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> 时被显式地设置，也可以在子迭代器是一个生成器时自动地设置（通过从子生成器返回一个值）。</p>
<blockquote>
<div><div class="versionchanged">
<p><span class="versionmodified changed">在 3.3 版更改: </span>添加 <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span> <span class="pre">&lt;expr&gt;</span></code> 以委托控制流给一个子迭代器。</p>
</div>
</div></blockquote>
<p>当yield表达式是赋值语句右侧的唯一表达式时，括号可以省略。</p>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<dl class="simple">
<dt><span class="target" id="index-105"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0255"><strong>PEP 255</strong></a> - 简单生成器</dt><dd><p>在 Python 中加入生成器和 <a class="reference internal" href="simple_stmts.html#yield"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">yield</span></code></a> 语句的提议。</p>
</dd>
<dt><span class="target" id="index-106"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0342"><strong>PEP 342</strong></a> - 通过增强型生成器实现协程</dt><dd><p>增强生成器 API 和语法的提议，使其可以被用作简单的协程。</p>
</dd>
<dt><span class="target" id="index-107"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0380"><strong>PEP 380</strong></a> - 委托给子生成器的语法</dt><dd><p>引入 <code class="xref std std-token docutils literal notranslate"><span class="pre">yield_from</span></code> 语法以方便地委托给子生成器的提议。</p>
</dd>
<dt><span class="target" id="index-108"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0525"><strong>PEP 525</strong></a> - 异步生成器</dt><dd><p>通过给协程函数加入生成器功能对 <span class="target" id="index-109"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0492"><strong>PEP 492</strong></a> 进行扩展的提议。</p>
</dd>
</dl>
</div>
<div class="section" id="generator-iterator-methods">
<span id="generator-methods"></span><span id="index-29"></span><h4><span class="section-number">6.2.9.1. </span>生成器-迭代器的方法<a class="headerlink" href="#generator-iterator-methods" title="永久链接至标题">¶</a></h4>
<p>这个子小节描述了生成器迭代器的方法。 它们可被用于控制生成器函数的执行。</p>
<p>请注意在生成器已经在执行时调用以下任何方法都会引发 <a class="reference internal" href="../library/exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ValueError</span></code></a> 异常。</p>
<span class="target" id="index-30"></span><dl class="method">
<dt id="generator.__next__">
<code class="sig-prename descclassname">generator.</code><code class="sig-name descname">__next__</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#generator.__next__" title="永久链接至目标">¶</a></dt>
<dd><p>开始一个生成器函数的执行或是从上次执行的 yield 表达式位置恢复执行。 当一个生成器函数通过 <a class="reference internal" href="#generator.__next__" title="generator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> 方法恢复执行时，当前的 yield 表达式总是取值为 <a class="reference internal" href="../library/constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>。 随后会继续执行到下一个 yield 表达式，其 <a class="reference internal" href="#grammar-token-expression-list"><code class="xref std std-token docutils literal notranslate"><span class="pre">expression_list</span></code></a> 的值会返回给 <a class="reference internal" href="#generator.__next__" title="generator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> 的调用者。 如果生成器没有产生下一个值就退出，则将引发 <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> 异常。</p>
<p>此方法通常是隐式地调用，例如通过 <a class="reference internal" href="compound_stmts.html#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a> 循环或是内置的 <a class="reference internal" href="../library/functions.html#next" title="next"><code class="xref py py-func docutils literal notranslate"><span class="pre">next()</span></code></a> 函数。</p>
</dd></dl>

<dl class="method">
<dt id="generator.send">
<code class="sig-prename descclassname">generator.</code><code class="sig-name descname">send</code><span class="sig-paren">(</span><em class="sig-param">value</em><span class="sig-paren">)</span><a class="headerlink" href="#generator.send" title="永久链接至目标">¶</a></dt>
<dd><p>恢复执行并向生成器函数“发送”一个值。 <em>value</em> 参数将成为当前 yield 表达式的结果。 <a class="reference internal" href="#generator.send" title="generator.send"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send()</span></code></a> 方法会返回生成器所产生的下一个值，或者如果生成器没有产生下一个值就退出则会引发 <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a>。 当调用 <a class="reference internal" href="#generator.send" title="generator.send"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send()</span></code></a> 来启动生成器时，它必须以 <a class="reference internal" href="../library/constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> 作为调用参数，因为这时没有可以接收值的 yield 表达式。</p>
</dd></dl>

<dl class="method">
<dt id="generator.throw">
<code class="sig-prename descclassname">generator.</code><code class="sig-name descname">throw</code><span class="sig-paren">(</span><em class="sig-param">type</em><span class="optional">[</span>, <em class="sig-param">value</em><span class="optional">[</span>, <em class="sig-param">traceback</em><span class="optional">]</span><span class="optional">]</span><span class="sig-paren">)</span><a class="headerlink" href="#generator.throw" title="永久链接至目标">¶</a></dt>
<dd><p>在生成器暂停的位置引发 <code class="docutils literal notranslate"><span class="pre">type</span></code> 类型的异常，并返回该生成器函数所产生的下一个值。 如果生成器没有产生下一个值就退出，则将引发 <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> 异常。 如果生成器函数没有捕获传入的异常，或引发了另一个异常，则该异常会被传播给调用者。</p>
</dd></dl>

<span class="target" id="index-31"></span><dl class="method">
<dt id="generator.close">
<code class="sig-prename descclassname">generator.</code><code class="sig-name descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#generator.close" title="永久链接至目标">¶</a></dt>
<dd><p>在生成器函数暂停的位置引发 <a class="reference internal" href="../library/exceptions.html#GeneratorExit" title="GeneratorExit"><code class="xref py py-exc docutils literal notranslate"><span class="pre">GeneratorExit</span></code></a>。 如果之后生成器函数正常退出、关闭或引发 <a class="reference internal" href="../library/exceptions.html#GeneratorExit" title="GeneratorExit"><code class="xref py py-exc docutils literal notranslate"><span class="pre">GeneratorExit</span></code></a> (由于未捕获该异常) 则关闭并返回其调用者。 如果生成器产生了一个值，关闭会引发 <a class="reference internal" href="../library/exceptions.html#RuntimeError" title="RuntimeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">RuntimeError</span></code></a>。 如果生成器引发任何其他异常，它会被传播给调用者。 如果生成器已经由于异常或正常退出则 <a class="reference internal" href="#generator.close" title="generator.close"><code class="xref py py-meth docutils literal notranslate"><span class="pre">close()</span></code></a> 不会做任何事。</p>
</dd></dl>

</div>
<div class="section" id="examples">
<span id="index-32"></span><h4><span class="section-number">6.2.9.2. </span>例子<a class="headerlink" href="#examples" title="永久链接至标题">¶</a></h4>
<p>这里是一个简单的例子，演示了生成器和生成器函数的行为:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">echo</span><span class="p">(</span><span class="n">value</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Execution starts when &#39;next()&#39; is called for the first time.&quot;</span><span class="p">)</span>
<span class="gp">... </span>    <span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>        <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="gp">... </span>            <span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>                <span class="n">value</span> <span class="o">=</span> <span class="p">(</span><span class="k">yield</span> <span class="n">value</span><span class="p">)</span>
<span class="gp">... </span>            <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
<span class="gp">... </span>                <span class="n">value</span> <span class="o">=</span> <span class="n">e</span>
<span class="gp">... </span>    <span class="k">finally</span><span class="p">:</span>
<span class="gp">... </span>        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Don&#39;t forget to clean up when &#39;close()&#39; is called.&quot;</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">generator</span> <span class="o">=</span> <span class="n">echo</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="n">generator</span><span class="p">))</span>
<span class="go">Execution starts when &#39;next()&#39; is called for the first time.</span>
<span class="go">1</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="nb">next</span><span class="p">(</span><span class="n">generator</span><span class="p">))</span>
<span class="go">None</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">generator</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="mi">2</span><span class="p">))</span>
<span class="go">2</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">generator</span><span class="o">.</span><span class="n">throw</span><span class="p">(</span><span class="ne">TypeError</span><span class="p">,</span> <span class="s2">&quot;spam&quot;</span><span class="p">)</span>
<span class="go">TypeError(&#39;spam&#39;,)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">generator</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="go">Don&#39;t forget to clean up when &#39;close()&#39; is called.</span>
</pre></div>
</div>
<p>对于 <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> 的例子, 参见“Python 有什么新变化”中的 <a class="reference internal" href="../whatsnew/3.3.html#pep-380"><span class="std std-ref">PEP 380: 委托给子生成器的语法</span></a>。</p>
</div>
<div class="section" id="asynchronous-generator-functions">
<span id="id3"></span><h4><span class="section-number">6.2.9.3. </span>异步生成器函数<a class="headerlink" href="#asynchronous-generator-functions" title="永久链接至标题">¶</a></h4>
<p>在一个使用 <a class="reference internal" href="compound_stmts.html#async-def"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">def</span></code></a> 定义的函数或方法中出现的 yield 表达式会进一步将该函数定义为一个 <a class="reference internal" href="../glossary.html#term-asynchronous-generator"><span class="xref std std-term">asynchronous generator</span></a> 函数。</p>
<p>当一个异步生成器函数被调用时，它会返回一个名为异步生成器对象的异步迭代器。 此对象将在之后控制该生成器函数的执行。 异步生成器对象通常被用在协程函数的 <a class="reference internal" href="compound_stmts.html#async-for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code></a> 语句中，类似于在 <a class="reference internal" href="compound_stmts.html#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a> 语句中使用生成器对象。</p>
<p>调用异步生成器的方法之一将返回 <a class="reference internal" href="../glossary.html#term-awaitable"><span class="xref std std-term">awaitable</span></a> 对象，执行会在此对象被等待时启动。 到那时，执行将前往第一个 yield 表达式，在那里它会再次暂停，将 <a class="reference internal" href="#grammar-token-expression-list"><code class="xref std std-token docutils literal notranslate"><span class="pre">expression_list</span></code></a> 的值返回给等待中的协程。 与生成器一样，挂起意味着局部的所有状态会被保留，包括局部变量的当前绑定、指令的指针、内部求值的堆栈以及任何异常处理的状态。 当执行在等待异步生成器的方法返回下一个对象后恢复时，该函数可以从原状态继续进行，就仿佛 yield 表达式只是另一个外部调用。 恢复执行之后 yield 表达式的值取决于恢复执行所用的方法。 如果使用 <a class="reference internal" href="#agen.__anext__" title="agen.__anext__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__anext__()</span></code></a> 则结果为 <a class="reference internal" href="../library/constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>。 否则的话，如果使用 <a class="reference internal" href="#agen.asend" title="agen.asend"><code class="xref py py-meth docutils literal notranslate"><span class="pre">asend()</span></code></a> 则结果将是传递给该方法的值。</p>
<p>在异步生成器函数中，yield 表达式允许出现在 <a class="reference internal" href="compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 结构的任何位置。 但是，如果一个异步生成器在其被终结（由于引用计数达到零或被作为垃圾回收）之前未被恢复，则then a yield expression within a <code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code> 结构中的 yield 表达式可能导致挂起的 <a class="reference internal" href="compound_stmts.html#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子句执行失败。 在此情况下，应由运行该异步生成器的事件循环或任务调度器来负责调用异步生成器-迭代器的 <a class="reference internal" href="#agen.aclose" title="agen.aclose"><code class="xref py py-meth docutils literal notranslate"><span class="pre">aclose()</span></code></a> 方法并运行所返回的协程对象，从而允许任何挂起的 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句得以执行。</p>
<p>为了能处理最终化，事件循环应该定义一个 <em>终结器</em> 函数，它接受一个异步生成器-迭代器且可能调用 <a class="reference internal" href="#agen.aclose" title="agen.aclose"><code class="xref py py-meth docutils literal notranslate"><span class="pre">aclose()</span></code></a> 并执行协程。 这个  <em>终结器</em> 可能通过调用 <a class="reference internal" href="../library/sys.html#sys.set_asyncgen_hooks" title="sys.set_asyncgen_hooks"><code class="xref py py-func docutils literal notranslate"><span class="pre">sys.set_asyncgen_hooks()</span></code></a> 来注册。 当首次迭代时，异步生成器-迭代器将保存已注册的 <em>终结器</em> 以便在最终化时调用。 有关For a reference example of a <em>终结器</em> 方法的参考示例请查看 <a class="reference external" href="https://github.com/python/cpython/tree/3.7/Lib/asyncio/base_events.py">Lib/asyncio/base_events.py</a> 中实现的 <code class="docutils literal notranslate"><span class="pre">asyncio.Loop.shutdown_asyncgens</span></code>。</p>
<p><code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span> <span class="pre">&lt;expr&gt;</span></code> 表达式如果在异步生成器函数中使用会引发语法错误。</p>
</div>
<div class="section" id="asynchronous-generator-iterator-methods">
<span id="asynchronous-generator-methods"></span><span id="index-33"></span><h4><span class="section-number">6.2.9.4. </span>异步生成器-迭代器方法<a class="headerlink" href="#asynchronous-generator-iterator-methods" title="永久链接至标题">¶</a></h4>
<p>这个子小节描述了异步生成器迭代器的方法，它们可被用于控制生成器函数的执行。</p>
<span class="target" id="index-34"></span><dl class="method">
<dt id="agen.__anext__">
<em class="property">coroutine </em><code class="sig-prename descclassname">agen.</code><code class="sig-name descname">__anext__</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#agen.__anext__" title="永久链接至目标">¶</a></dt>
<dd><p>返回一个可等待对象，它在运行时会开始执行该异步生成器或是从上次执行的 yield 表达式位置恢复执行。 当一个异步生成器函数通过 <a class="reference internal" href="#agen.__anext__" title="agen.__anext__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__anext__()</span></code></a> 方法恢复执行时，当前的 yield 表达式所返回的可等待对象总是取值为 <a class="reference internal" href="../library/constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>，它在运行时将继续执行到下一个 yield 表达式。 该 yield 表达式的 <a class="reference internal" href="#grammar-token-expression-list"><code class="xref std std-token docutils literal notranslate"><span class="pre">expression_list</span></code></a> 的值会是完成的协程所引发的 <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> 异常的值。 如果异步生成器没有产生下一个值就退出，则该可等待对象将引发 <a class="reference internal" href="../library/exceptions.html#StopAsyncIteration" title="StopAsyncIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopAsyncIteration</span></code></a> 异常，提示该异步迭代操作已完成。</p>
<p>此方法通常是通过 <a class="reference internal" href="compound_stmts.html#async-for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code></a> 循环隐式地调用。</p>
</dd></dl>

<dl class="method">
<dt id="agen.asend">
<em class="property">coroutine </em><code class="sig-prename descclassname">agen.</code><code class="sig-name descname">asend</code><span class="sig-paren">(</span><em class="sig-param">value</em><span class="sig-paren">)</span><a class="headerlink" href="#agen.asend" title="永久链接至目标">¶</a></dt>
<dd><p>返回一个可等待对象，它在运行时会恢复该异步生成器的执行。 与生成器的 <a class="reference internal" href="#generator.send" title="generator.send"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send()</span></code></a> 方法一样，此方法会“发送”一个值给异步生成器函数，其 <em>value</em> 参数会成为当前 yield 表达式的结果值。 <a class="reference internal" href="#agen.asend" title="agen.asend"><code class="xref py py-meth docutils literal notranslate"><span class="pre">asend()</span></code></a> 方法所返回的可等待对象将返回生成器产生的下一个值，其值为所引发的 <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a>，或者如果异步生成器没有产生下一个值就退出则引发 <a class="reference internal" href="../library/exceptions.html#StopAsyncIteration" title="StopAsyncIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopAsyncIteration</span></code></a>。 当调用 <a class="reference internal" href="#agen.asend" title="agen.asend"><code class="xref py py-meth docutils literal notranslate"><span class="pre">asend()</span></code></a> 来启动异步生成器时，它必须以 <a class="reference internal" href="../library/constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> 作为调用参数，因为这时没有可以接收值的 yield 表达式。</p>
</dd></dl>

<dl class="method">
<dt id="agen.athrow">
<em class="property">coroutine </em><code class="sig-prename descclassname">agen.</code><code class="sig-name descname">athrow</code><span class="sig-paren">(</span><em class="sig-param">type</em><span class="optional">[</span>, <em class="sig-param">value</em><span class="optional">[</span>, <em class="sig-param">traceback</em><span class="optional">]</span><span class="optional">]</span><span class="sig-paren">)</span><a class="headerlink" href="#agen.athrow" title="永久链接至目标">¶</a></dt>
<dd><p>返回一个可等待对象，它会在异步生成器暂停的位置引发 <code class="docutils literal notranslate"><span class="pre">type</span></code> 类型的异常，并返回该生成器函数所产生的下一个值，其值为所引发的 <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> 异常。 如果异步生成器没有产生下一个值就退出，则将由该可等待对象引发 <a class="reference internal" href="../library/exceptions.html#StopAsyncIteration" title="StopAsyncIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopAsyncIteration</span></code></a> 异步。 如果生成器函数没有捕获传入的异常，或引发了另一个异常，则当可等待对象运行时该异常会被传播给可等待对象的调用者。</p>
</dd></dl>

<span class="target" id="index-35"></span><dl class="method">
<dt id="agen.aclose">
<em class="property">coroutine </em><code class="sig-prename descclassname">agen.</code><code class="sig-name descname">aclose</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#agen.aclose" title="永久链接至目标">¶</a></dt>
<dd><p>返回一个可等待对象，它会在运行时向异步生成器函数暂停的位置抛入一个 <a class="reference internal" href="../library/exceptions.html#GeneratorExit" title="GeneratorExit"><code class="xref py py-exc docutils literal notranslate"><span class="pre">GeneratorExit</span></code></a>。 如果该异步生成器函数正常退出、关闭或引发 <a class="reference internal" href="../library/exceptions.html#GeneratorExit" title="GeneratorExit"><code class="xref py py-exc docutils literal notranslate"><span class="pre">GeneratorExit</span></code></a> (由于未捕获该异常) 则返回的可等待对象将引发 <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> 异常。 后续调用异步生成器所返回的任何其他可等待对象将引发 <a class="reference internal" href="../library/exceptions.html#StopAsyncIteration" title="StopAsyncIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopAsyncIteration</span></code></a> 异常。 如果异步生成器产生了一个值，该可等待对象会引发 <a class="reference internal" href="../library/exceptions.html#RuntimeError" title="RuntimeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">RuntimeError</span></code></a>。 如果异步生成器引发任何其他异常，它会被传播给可等待对象的调用者。 如果异步生成器已经由于异常或正常退出则后续调用 <a class="reference internal" href="#agen.aclose" title="agen.aclose"><code class="xref py py-meth docutils literal notranslate"><span class="pre">aclose()</span></code></a> 将返回一个不会做任何事的可等待对象。</p>
</dd></dl>

</div>
</div>
</div>
<div class="section" id="primaries">
<span id="id4"></span><h2><span class="section-number">6.3. </span>原型<a class="headerlink" href="#primaries" title="永久链接至标题">¶</a></h2>
<p id="index-36">原型代表编程语言中最紧密绑定的操作。 它们的句法如下:</p>
<pre>
<strong id="grammar-token-primary">primary</strong> ::=  <a class="reference internal" href="#grammar-token-atom"><code class="xref docutils literal notranslate"><span class="pre">atom</span></code></a> | <a class="reference internal" href="#grammar-token-attributeref"><code class="xref docutils literal notranslate"><span class="pre">attributeref</span></code></a> | <a class="reference internal" href="#grammar-token-subscription"><code class="xref docutils literal notranslate"><span class="pre">subscription</span></code></a> | <a class="reference internal" href="#grammar-token-slicing"><code class="xref docutils literal notranslate"><span class="pre">slicing</span></code></a> | <a class="reference internal" href="#grammar-token-call"><code class="xref docutils literal notranslate"><span class="pre">call</span></code></a>
</pre>
<div class="section" id="attribute-references">
<span id="id5"></span><h3><span class="section-number">6.3.1. </span>属性引用<a class="headerlink" href="#attribute-references" title="永久链接至标题">¶</a></h3>
<p id="index-37">属性引用是后面带有一个句点加一个名称的原型:</p>
<pre>
<strong id="grammar-token-attributeref">attributeref</strong> ::=  <a class="reference internal" href="#grammar-token-primary"><code class="xref docutils literal notranslate"><span class="pre">primary</span></code></a> &quot;.&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>
</pre>
<p id="index-38">此原型必须求值为一个支持属性引用的类型的对象，多数对象都支持属性引用。 随后该对象会被要求产生以指定标识符为名称的属性。 这个产生过程可通过重载 <a class="reference internal" href="datamodel.html#object.__getattr__" title="object.__getattr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__getattr__()</span></code></a> 方法来自定义。 如果这个属性不可用，则将引发 <a class="reference internal" href="../library/exceptions.html#AttributeError" title="AttributeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">AttributeError</span></code></a> 异常。 否则的话，所产生对象的类型和值会根据该对象来确定。 对同一属性引用的多次求值可能产生不同的对象。</p>
</div>
<div class="section" id="subscriptions">
<span id="id6"></span><h3><span class="section-number">6.3.2. </span>抽取<a class="headerlink" href="#subscriptions" title="永久链接至标题">¶</a></h3>
<span class="target" id="index-39"></span><p id="index-40">抽取就是在序列（字符串、元组或列表）或映射（字典）对象中选择一项:</p>
<pre>
<strong id="grammar-token-subscription">subscription</strong> ::=  <a class="reference internal" href="#grammar-token-primary"><code class="xref docutils literal notranslate"><span class="pre">primary</span></code></a> &quot;[&quot; <a class="reference internal" href="#grammar-token-expression-list"><code class="xref docutils literal notranslate"><span class="pre">expression_list</span></code></a> &quot;]&quot;
</pre>
<p>此原型必须求值为一个支持抽取操作的对象（例如列表或字典）。 用户定义的对象可通过定义 <a class="reference internal" href="datamodel.html#object.__getitem__" title="object.__getitem__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__getitem__()</span></code></a> 方法来支持抽取操作。</p>
<p>对于内置对象，有两种类型的对象支持抽取操作:</p>
<p>如果原型为映射，表达式列表必须求值为一个以该映射的键为值的对象，抽取操作会在映射中选出该键所对应的值。（表达式列表为一个元组，除非其中只有一项。）</p>
<p>如果原型为序列，表达式列表必须求值为一个整数或一个切片（详情见下节）。</p>
<p>正式句法规则并没有在序列中设置负标号的特殊保留条款；但是，内置序列所提供的 <a class="reference internal" href="datamodel.html#object.__getitem__" title="object.__getitem__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__getitem__()</span></code></a> 方法都可通过在索引中添加序列长度来解析负标号 (这样 <code class="docutils literal notranslate"><span class="pre">x[-1]</span></code> 会选出 <code class="docutils literal notranslate"><span class="pre">x</span></code> 中的最后一项)。 结果值必须为一个小于序列中项数的非负整数，抽取操作会选出标号为该值的项（从零开始数）。 由于对负标号和切片的支持存在于对象的 <a class="reference internal" href="datamodel.html#object.__getitem__" title="object.__getitem__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__getitem__()</span></code></a> 方法，重载此方法的子类需要显式地添加这种支持。</p>
<p id="index-41">字符串的项是字符。 字符不是单独的数据类型而是仅有一个字符的字符串。</p>
</div>
<div class="section" id="slicings">
<span id="id7"></span><h3><span class="section-number">6.3.3. </span>切片<a class="headerlink" href="#slicings" title="永久链接至标题">¶</a></h3>
<span class="target" id="index-42"></span><p id="index-43">切片就是在序列对象（字符串、元组或列表）中选择某个范围内的项。 切片可被用作表达式以及赋值或 <a class="reference internal" href="simple_stmts.html#del"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">del</span></code></a> 语句的目标。 切片的句法如下:</p>
<pre>
<strong id="grammar-token-slicing">slicing     </strong> ::=  <a class="reference internal" href="#grammar-token-primary"><code class="xref docutils literal notranslate"><span class="pre">primary</span></code></a> &quot;[&quot; <a class="reference internal" href="#grammar-token-slice-list"><code class="xref docutils literal notranslate"><span class="pre">slice_list</span></code></a> &quot;]&quot;
<strong id="grammar-token-slice-list">slice_list  </strong> ::=  <a class="reference internal" href="#grammar-token-slice-item"><code class="xref docutils literal notranslate"><span class="pre">slice_item</span></code></a> (&quot;,&quot; <a class="reference internal" href="#grammar-token-slice-item"><code class="xref docutils literal notranslate"><span class="pre">slice_item</span></code></a>)* [&quot;,&quot;]
<strong id="grammar-token-slice-item">slice_item  </strong> ::=  <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> | <a class="reference internal" href="#grammar-token-proper-slice"><code class="xref docutils literal notranslate"><span class="pre">proper_slice</span></code></a>
<strong id="grammar-token-proper-slice">proper_slice</strong> ::=  [<a class="reference internal" href="#grammar-token-lower-bound"><code class="xref docutils literal notranslate"><span class="pre">lower_bound</span></code></a>] &quot;:&quot; [<a class="reference internal" href="#grammar-token-upper-bound"><code class="xref docutils literal notranslate"><span class="pre">upper_bound</span></code></a>] [ &quot;:&quot; [<a class="reference internal" href="#grammar-token-stride"><code class="xref docutils literal notranslate"><span class="pre">stride</span></code></a>] ]
<strong id="grammar-token-lower-bound">lower_bound </strong> ::=  <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>
<strong id="grammar-token-upper-bound">upper_bound </strong> ::=  <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>
<strong id="grammar-token-stride">stride      </strong> ::=  <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>
</pre>
<p>此处的正式句法中存在一点歧义：任何形似表达式列表的东西同样也会形似切片列表，因此任何抽取操作也可以被解析为切片。 为了不使句法更加复杂，于是通过定义将此情况解析为抽取优先于解析为切片来消除这种歧义（切片列表未包含正确的切片就属于此情况）。</p>
<p id="index-44">切片的语义如下所述。 元型通过一个根据下面的切片列表来构造的键进行索引（与普通抽取一样使用 <a class="reference internal" href="datamodel.html#object.__getitem__" title="object.__getitem__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__getitem__()</span></code></a> 方法）。 如果切片列表包含至少一个逗号，则键将是一个包含切片项转换的元组；否则的话，键将是单个切片项的转换。 切片项如为一个表达式，则其转换就是该表达式。 一个正确切片的转换就是一个切片对象（参见 <a class="reference internal" href="datamodel.html#types"><span class="std std-ref">标准类型层级结构</span></a> 一节），该对象的 <code class="xref py py-attr docutils literal notranslate"><span class="pre">start</span></code>, <code class="xref py py-attr docutils literal notranslate"><span class="pre">stop</span></code> 和 <code class="xref py py-attr docutils literal notranslate"><span class="pre">step</span></code> 属性将分别为表达式所给出的下界、上界和步长值，省略的表达式将用 <code class="docutils literal notranslate"><span class="pre">None</span></code> 来替换。</p>
</div>
<div class="section" id="calls">
<span id="index-45"></span><span id="id8"></span><h3><span class="section-number">6.3.4. </span>调用<a class="headerlink" href="#calls" title="永久链接至标题">¶</a></h3>
<p>所谓调用就是附带可能为空的一系列 <a class="reference internal" href="../glossary.html#term-argument"><span class="xref std std-term">参数</span></a> 来执行一个可调用对象 (例如 <a class="reference internal" href="../glossary.html#term-function"><span class="xref std std-term">function</span></a>):</p>
<pre>
<strong id="grammar-token-call">call                </strong> ::=  <a class="reference internal" href="#grammar-token-primary"><code class="xref docutils literal notranslate"><span class="pre">primary</span></code></a> &quot;(&quot; [<a class="reference internal" href="#grammar-token-argument-list"><code class="xref docutils literal notranslate"><span class="pre">argument_list</span></code></a> [&quot;,&quot;] | <a class="reference internal" href="#grammar-token-comprehension"><code class="xref docutils literal notranslate"><span class="pre">comprehension</span></code></a>] &quot;)&quot;
<strong id="grammar-token-argument-list">argument_list       </strong> ::=  <a class="reference internal" href="#grammar-token-positional-arguments"><code class="xref docutils literal notranslate"><span class="pre">positional_arguments</span></code></a> [&quot;,&quot; <a class="reference internal" href="#grammar-token-starred-and-keywords"><code class="xref docutils literal notranslate"><span class="pre">starred_and_keywords</span></code></a>]
                            [&quot;,&quot; <a class="reference internal" href="#grammar-token-keywords-arguments"><code class="xref docutils literal notranslate"><span class="pre">keywords_arguments</span></code></a>]
                          | <a class="reference internal" href="#grammar-token-starred-and-keywords"><code class="xref docutils literal notranslate"><span class="pre">starred_and_keywords</span></code></a> [&quot;,&quot; <a class="reference internal" href="#grammar-token-keywords-arguments"><code class="xref docutils literal notranslate"><span class="pre">keywords_arguments</span></code></a>]
                          | <a class="reference internal" href="#grammar-token-keywords-arguments"><code class="xref docutils literal notranslate"><span class="pre">keywords_arguments</span></code></a>
<strong id="grammar-token-positional-arguments">positional_arguments</strong> ::=  [&quot;*&quot;] <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> (&quot;,&quot; [&quot;*&quot;] <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>)*
<strong id="grammar-token-starred-and-keywords">starred_and_keywords</strong> ::=  (&quot;*&quot; <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> | <a class="reference internal" href="#grammar-token-keyword-item"><code class="xref docutils literal notranslate"><span class="pre">keyword_item</span></code></a>)
                          (&quot;,&quot; &quot;*&quot; <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> | &quot;,&quot; <a class="reference internal" href="#grammar-token-keyword-item"><code class="xref docutils literal notranslate"><span class="pre">keyword_item</span></code></a>)*
<strong id="grammar-token-keywords-arguments">keywords_arguments  </strong> ::=  (<a class="reference internal" href="#grammar-token-keyword-item"><code class="xref docutils literal notranslate"><span class="pre">keyword_item</span></code></a> | &quot;**&quot; <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>)
                          (&quot;,&quot; <a class="reference internal" href="#grammar-token-keyword-item"><code class="xref docutils literal notranslate"><span class="pre">keyword_item</span></code></a> | &quot;,&quot; &quot;**&quot; <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>)*
<strong id="grammar-token-keyword-item">keyword_item        </strong> ::=  <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a> &quot;=&quot; <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>
</pre>
<p>一个可选项为在位置和关键字参数后加上逗号而不影响语义。</p>
<p id="index-46">此原型必须求值为一个可调用对象（用户定义的函数，内置函数，内置对象的方法，类对象，类实例的方法以及任何具有 <a class="reference internal" href="datamodel.html#object.__call__" title="object.__call__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__call__()</span></code></a> 方法的对象都是可调用对象）。 所有参数表达式将在尝试调用前被求值。 请参阅 <a class="reference internal" href="compound_stmts.html#function"><span class="std std-ref">函数定义</span></a> 一节了解正式的 <a class="reference internal" href="../glossary.html#term-parameter"><span class="xref std std-term">parameter</span></a> 列表句法。</p>
<p>如果存在关键字参数，它们会先通过以下操作被转换为位置参数。 首先，为正式参数创建一个未填充空位的列表. 如果有 N 个位置参数，则将它们放入前 N 个空位。 然后，对于每个关键字参数，使用标识符来确定其对应的空位（如果标识符与第一个正式参数名相同则使用第一个个空位，依此类推）。 如果空位已被填充，则会引发 <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> 异常。 否则，将参数值放入空位进行填充（即使表达式为 <code class="docutils literal notranslate"><span class="pre">None</span></code> 也会填充空位）。 当所有参数处理完毕时，尚未填充的空位将用来自函数定义的相应默认值来填充。 （函数一旦定义其参数默认值就会被计算；因此，当列表或字典这类可变对象被用作默认值时，将会被所有未指定相应空位参数值的调用所共享；这种情况通常应当避免。） 如果任何一个未填充空位没有指定默认值，则会引发 <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> 异常。 否则的话，已填充空位的列表会被作为调用的参数列表。</p>
<div class="impl-detail compound">
<p><strong>CPython implementation detail:</strong> 某些实现可能提供位置参数没有名称的内置函数，即使它们在文档说明的场合下有“命名”，因此不能以关键字形式提供参数。 在 CPython 中，以 C 编写并使用 <a class="reference internal" href="../c-api/arg.html#c.PyArg_ParseTuple" title="PyArg_ParseTuple"><code class="xref c c-func docutils literal notranslate"><span class="pre">PyArg_ParseTuple()</span></code></a> 来解析其参数的函数实现就属于这种情况。</p>
</div>
<p>如果存在比正式参数空位多的位置参数，将会引发 <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> 异常，除非有一个正式参数使用了 <code class="docutils literal notranslate"><span class="pre">*identifier</span></code> 句法；在此情况下，该正式参数将接受一个包含了多余位置参数的元组（如果没有多余位置参数则为一个空元组）。</p>
<p>如果任何关键字参数没有与之对应的正式参数名称，将会引发 <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> 异常，除非有一个正式参数使用了 <code class="docutils literal notranslate"><span class="pre">**identifier</span></code> 句法，该正式参数将接受一个包含了多余关键字参数的字典（使用关键字作为键而参数值作为与键对应的值），如果没有多余关键字参数则为一个（新的）空字典。</p>
<p id="index-47">如果函数调用中出现了 <code class="docutils literal notranslate"><span class="pre">*expression</span></code> 句法，<code class="docutils literal notranslate"><span class="pre">expression</span></code> 必须求值为一个 <a class="reference internal" href="../glossary.html#term-iterable"><span class="xref std std-term">iterable</span></a>。 来自该可迭代对象的元素会被当作是额外的位置参数。 对于 <code class="docutils literal notranslate"><span class="pre">f(x1,</span> <span class="pre">x2,</span> <span class="pre">*y,</span> <span class="pre">x3,</span> <span class="pre">x4)</span></code> 调用，如果 <em>y</em> 求值为一个序列 <em>y1</em>, ..., <em>yM</em>，则它就等价于一个带有 M+4 个位置参数 <em>x1</em>, <em>x2</em>, <em>y1</em>, ..., <em>yM</em>, <em>x3</em>, <em>x4</em> 的调用。</p>
<p>这样做的一个后果是虽然 <code class="docutils literal notranslate"><span class="pre">*expression</span></code> 句法可能出现于显式的关键字参数 <em>之后</em>，但它会在关键字参数（以及任何 <code class="docutils literal notranslate"><span class="pre">**expression</span></code> 参数 -- 见下文） <em>之前</em> 被处理。 因此:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">f</span><span class="p">(</span><span class="n">b</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="o">*</span><span class="p">(</span><span class="mi">2</span><span class="p">,))</span>
<span class="go">2 1</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">f</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="o">*</span><span class="p">(</span><span class="mi">2</span><span class="p">,))</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">1</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">TypeError</span>: <span class="n">f() got multiple values for keyword argument &#39;a&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">f</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="o">*</span><span class="p">(</span><span class="mi">2</span><span class="p">,))</span>
<span class="go">1 2</span>
</pre></div>
</div>
<p>在同一个调用中同时使用关键字参数和 <code class="docutils literal notranslate"><span class="pre">*expression</span></code> 句法并不常见，因此实际上这样的混淆不会发生。</p>
<p id="index-48">如果函数调用中出现了 <code class="docutils literal notranslate"><span class="pre">**expression</span></code> 句法，<code class="docutils literal notranslate"><span class="pre">expression</span></code> 必须求值为一个 <a class="reference internal" href="../glossary.html#term-mapping"><span class="xref std std-term">mapping</span></a>，其内容会被当作是额外的关键字参数。 如果一个关键字已存在（作为显式关键字参数，或来自另一个拆包），则将引发 <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> 异常。</p>
<p>使用 <code class="docutils literal notranslate"><span class="pre">*identifier</span></code> 或 <code class="docutils literal notranslate"><span class="pre">**identifier</span></code> 句法的正式参数不能被用作位置参数空位或关键字参数名称。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.5 版更改: </span>函数调用接受任意数量的 <code class="docutils literal notranslate"><span class="pre">*</span></code> 和 <code class="docutils literal notranslate"><span class="pre">**</span></code> 拆包，位置参数可能跟在可迭代对象拆包 (<code class="docutils literal notranslate"><span class="pre">*</span></code>) 之后，而关键字参数可能跟在字典拆包 (<code class="docutils literal notranslate"><span class="pre">**</span></code>) 之后。 由 <span class="target" id="index-110"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0448"><strong>PEP 448</strong></a> 发起最初提议。</p>
</div>
<p>除非引发了异常，调用总是会有返回值，返回值也可能为 <code class="docutils literal notranslate"><span class="pre">None</span></code>。 返回值的计算方式取决于可调用对象的类型。</p>
<p>如果类型为---</p>
<dl>
<dt>用户自定义函数:</dt><dd><p id="index-50">函数的代码块会被执行，并向其传入参数列表。 代码块所做的第一件事是将正式形参绑定到对应参数；相关描述参见 <a class="reference internal" href="compound_stmts.html#function"><span class="std std-ref">函数定义</span></a> 一节。 当代码块执行 <a class="reference internal" href="simple_stmts.html#return"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code></a> 语句时，由其指定函数调用的返回值。</p>
</dd>
<dt>内置函数或方法:</dt><dd><p id="index-51">具体结果依赖于解释器；有关内置函数和方法的描述参见 <a class="reference internal" href="../library/functions.html#built-in-funcs"><span class="std std-ref">内置函数</span></a>。</p>
</dd>
<dt>类对象:</dt><dd><p id="index-52">返回该类的一个新实例。</p>
</dd>
<dt>类实例方法:</dt><dd><p id="index-53">调用相应的用户自定义函数，向其传入的参数列表会比调用的参数列表多一项：该实例将成为第一个参数。</p>
</dd>
<dt>类实例:</dt><dd><p id="index-54">该类必须定义有 <a class="reference internal" href="datamodel.html#object.__call__" title="object.__call__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__call__()</span></code></a> 方法；作用效果将等价于调用该方法。</p>
</dd>
</dl>
</div>
</div>
<div class="section" id="await-expression">
<span id="await"></span><span id="index-55"></span><h2><span class="section-number">6.4. </span>await 表达式<a class="headerlink" href="#await-expression" title="永久链接至标题">¶</a></h2>
<p>挂起 <a class="reference internal" href="../glossary.html#term-coroutine"><span class="xref std std-term">coroutine</span></a> 的执行以等待一个 <a class="reference internal" href="../glossary.html#term-awaitable"><span class="xref std std-term">awaitable</span></a> 对象。 只能在 <a class="reference internal" href="../glossary.html#term-coroutine-function"><span class="xref std std-term">coroutine function</span></a> 内部使用。</p>
<pre>
<strong id="grammar-token-await-expr">await_expr</strong> ::=  &quot;await&quot; <a class="reference internal" href="#grammar-token-primary"><code class="xref docutils literal notranslate"><span class="pre">primary</span></code></a>
</pre>
<div class="versionadded">
<p><span class="versionmodified added">3.5 新版功能.</span></p>
</div>
</div>
<div class="section" id="the-power-operator">
<span id="power"></span><h2><span class="section-number">6.5. </span>幂运算符<a class="headerlink" href="#the-power-operator" title="永久链接至标题">¶</a></h2>
<p id="index-56">幂运算符的绑定比在其左侧的一元运算符更紧密；但绑定紧密程度不及在其右侧的一元运算符。 句法如下:</p>
<pre>
<strong id="grammar-token-power">power</strong> ::=  (<a class="reference internal" href="#grammar-token-await-expr"><code class="xref docutils literal notranslate"><span class="pre">await_expr</span></code></a> | <a class="reference internal" href="#grammar-token-primary"><code class="xref docutils literal notranslate"><span class="pre">primary</span></code></a>) [&quot;**&quot; <a class="reference internal" href="#grammar-token-u-expr"><code class="xref docutils literal notranslate"><span class="pre">u_expr</span></code></a>]
</pre>
<p>因此，在一个未加圆括号的幂运算符和单目运算符序列中，运算符将从右向左求值（这不会限制操作数的求值顺序）: <code class="docutils literal notranslate"><span class="pre">-1**2</span></code> 结果将为 <code class="docutils literal notranslate"><span class="pre">-1</span></code>。</p>
<p>幂运算符与附带两个参数调用内置 <a class="reference internal" href="../library/functions.html#pow" title="pow"><code class="xref py py-func docutils literal notranslate"><span class="pre">pow()</span></code></a> 函数具有相同的语义：结果为对其左参数进行其右参数所指定幂次的乘方运算。 数值参数会先转换为相同类型，结果也为转换后的类型。</p>
<p>对于 int 类型的操作数，结果将具有与操作数相同的类型，除非第二个参数为负数；在那种情况下，所有参数会被转换为 float 类型并输出 float 类型的结果。 例如，<code class="docutils literal notranslate"><span class="pre">10**2</span></code> 返回 <code class="docutils literal notranslate"><span class="pre">100</span></code>，而 <code class="docutils literal notranslate"><span class="pre">10**-2</span></code> 返回 <code class="docutils literal notranslate"><span class="pre">0.01</span></code>。</p>
<p>对 <code class="docutils literal notranslate"><span class="pre">0.0</span></code> 进行负数幂次运算将导致 <a class="reference internal" href="../library/exceptions.html#ZeroDivisionError" title="ZeroDivisionError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code></a>。 对负数进行分数幂次运算将返回 <a class="reference internal" href="../library/functions.html#complex" title="complex"><code class="xref py py-class docutils literal notranslate"><span class="pre">complex</span></code></a> 数值。 （在早期版本中这将引发 <a class="reference internal" href="../library/exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ValueError</span></code></a>。）</p>
</div>
<div class="section" id="unary-arithmetic-and-bitwise-operations">
<span id="unary"></span><h2><span class="section-number">6.6. </span>一元算术和位运算<a class="headerlink" href="#unary-arithmetic-and-bitwise-operations" title="永久链接至标题">¶</a></h2>
<p id="index-57">所有算术和位运算具有相同的优先级:</p>
<pre>
<strong id="grammar-token-u-expr">u_expr</strong> ::=  <a class="reference internal" href="#grammar-token-power"><code class="xref docutils literal notranslate"><span class="pre">power</span></code></a> | &quot;-&quot; <a class="reference internal" href="#grammar-token-u-expr"><code class="xref docutils literal notranslate"><span class="pre">u_expr</span></code></a> | &quot;+&quot; <a class="reference internal" href="#grammar-token-u-expr"><code class="xref docutils literal notranslate"><span class="pre">u_expr</span></code></a> | &quot;~&quot; <a class="reference internal" href="#grammar-token-u-expr"><code class="xref docutils literal notranslate"><span class="pre">u_expr</span></code></a>
</pre>
<p id="index-58">一元运算符 <code class="docutils literal notranslate"><span class="pre">-</span></code> (负) 会产生其数值参数的负值。</p>
<p id="index-59">一元运算符 <code class="docutils literal notranslate"><span class="pre">+</span></code> (正) 会产生与其数值参数相同的值。</p>
<p id="index-60">一元运算符 <code class="docutils literal notranslate"><span class="pre">~</span></code> (取反) 的结果是对其整数参数按位取反。 <code class="docutils literal notranslate"><span class="pre">x</span></code> 的按位取反被定义为 <code class="docutils literal notranslate"><span class="pre">-(x+1)</span></code>。 它只作用于整数。</p>
<p id="index-61">在所有三种情况下，如果参数的类型不正确，将引发 <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> 异常。</p>
</div>
<div class="section" id="binary-arithmetic-operations">
<span id="binary"></span><h2><span class="section-number">6.7. </span>二元算术运算符<a class="headerlink" href="#binary-arithmetic-operations" title="永久链接至标题">¶</a></h2>
<p id="index-62">二元算术运算符遵循传统的优先级。 请注意某些此类运算符也作用于特定的非数字类型。 除幂运算符以外只有两个优先级别，一个作用于乘法型运算符，另一个作用于加法型运算符:</p>
<pre>
<strong id="grammar-token-m-expr">m_expr</strong> ::=  <a class="reference internal" href="#grammar-token-u-expr"><code class="xref docutils literal notranslate"><span class="pre">u_expr</span></code></a> | <a class="reference internal" href="#grammar-token-m-expr"><code class="xref docutils literal notranslate"><span class="pre">m_expr</span></code></a> &quot;*&quot; <a class="reference internal" href="#grammar-token-u-expr"><code class="xref docutils literal notranslate"><span class="pre">u_expr</span></code></a> | <a class="reference internal" href="#grammar-token-m-expr"><code class="xref docutils literal notranslate"><span class="pre">m_expr</span></code></a> &quot;&#64;&quot; <a class="reference internal" href="#grammar-token-m-expr"><code class="xref docutils literal notranslate"><span class="pre">m_expr</span></code></a> |
            <a class="reference internal" href="#grammar-token-m-expr"><code class="xref docutils literal notranslate"><span class="pre">m_expr</span></code></a> &quot;//&quot; <a class="reference internal" href="#grammar-token-u-expr"><code class="xref docutils literal notranslate"><span class="pre">u_expr</span></code></a> | <a class="reference internal" href="#grammar-token-m-expr"><code class="xref docutils literal notranslate"><span class="pre">m_expr</span></code></a> &quot;/&quot; <a class="reference internal" href="#grammar-token-u-expr"><code class="xref docutils literal notranslate"><span class="pre">u_expr</span></code></a> |
            <a class="reference internal" href="#grammar-token-m-expr"><code class="xref docutils literal notranslate"><span class="pre">m_expr</span></code></a> &quot;%&quot; <a class="reference internal" href="#grammar-token-u-expr"><code class="xref docutils literal notranslate"><span class="pre">u_expr</span></code></a>
<strong id="grammar-token-a-expr">a_expr</strong> ::=  <a class="reference internal" href="#grammar-token-m-expr"><code class="xref docutils literal notranslate"><span class="pre">m_expr</span></code></a> | <a class="reference internal" href="#grammar-token-a-expr"><code class="xref docutils literal notranslate"><span class="pre">a_expr</span></code></a> &quot;+&quot; <a class="reference internal" href="#grammar-token-m-expr"><code class="xref docutils literal notranslate"><span class="pre">m_expr</span></code></a> | <a class="reference internal" href="#grammar-token-a-expr"><code class="xref docutils literal notranslate"><span class="pre">a_expr</span></code></a> &quot;-&quot; <a class="reference internal" href="#grammar-token-m-expr"><code class="xref docutils literal notranslate"><span class="pre">m_expr</span></code></a>
</pre>
<p id="index-63">运算符 <code class="docutils literal notranslate"><span class="pre">*</span></code> (乘) 将输出其参数的乘积。 两个参数或者必须都为数字，或者一个参数必须为整数而另一个参数必须为序列。 在前一种情况下，两个数字将被转换为相同类型然后相乘。 在后一种情况下，将执行序列的重复；重复因子为负数将输出空序列。</p>
<p id="index-64">运算符 <code class="docutils literal notranslate"><span class="pre">&#64;</span></code> (at) 的目标是用于矩阵乘法。 没有内置 Python 类型实现此运算符。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.5 新版功能.</span></p>
</div>
<p id="index-65">运算符 <code class="docutils literal notranslate"><span class="pre">/</span></code> (除) 和 <code class="docutils literal notranslate"><span class="pre">//</span></code> (整除) 将输出其参数的商。 两个数字参数将先被转换为相同类型。 整数相除会输出一个 float 值，整数相整除的结果仍是整数；整除的结果就是使用 'floor' 函数进行算术除法的结果。 除以零的运算将引发 <a class="reference internal" href="../library/exceptions.html#ZeroDivisionError" title="ZeroDivisionError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code></a> 异常。</p>
<p id="index-66">运算符 <code class="docutils literal notranslate"><span class="pre">%</span></code> (模) 将输出第一个参数除以第二个参数的余数。 两个数字参数将先被转换为相同类型。 右参数为零将引发 <a class="reference internal" href="../library/exceptions.html#ZeroDivisionError" title="ZeroDivisionError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code></a> 异常。 参数可以为浮点数，例如 <code class="docutils literal notranslate"><span class="pre">3.14%0.7</span></code> 等于 <code class="docutils literal notranslate"><span class="pre">0.34</span></code> (因为 <code class="docutils literal notranslate"><span class="pre">3.14</span></code> 等于 <code class="docutils literal notranslate"><span class="pre">4*0.7</span> <span class="pre">+</span> <span class="pre">0.34</span></code>)。 模运算符的结果的正负总是与第二个操作数一致（或是为零）；结果的绝对值一定小于第二个操作数的绝对值 <a class="footnote-reference brackets" href="#id17" id="id9">1</a>。</p>
<p>整除与模运算符的联系可通过以下等式说明: <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">(x//y)*y</span> <span class="pre">+</span> <span class="pre">(x%y)</span></code>。 此外整除与模也可通过内置函数 <a class="reference internal" href="../library/functions.html#divmod" title="divmod"><code class="xref py py-func docutils literal notranslate"><span class="pre">divmod()</span></code></a> 来同时进行: <code class="docutils literal notranslate"><span class="pre">divmod(x,</span> <span class="pre">y)</span> <span class="pre">==</span> <span class="pre">(x//y,</span> <span class="pre">x%y)</span></code>。 <a class="footnote-reference brackets" href="#id18" id="id10">2</a>。</p>
<p>除了对数字执行模运算，运算符 <code class="docutils literal notranslate"><span class="pre">%</span></code> 还被字符串对象重载用于执行旧式的字符串格式化（又称插值）。 字符串格式化句法的描述参见 Python 库参考的 <a class="reference internal" href="../library/stdtypes.html#old-string-formatting"><span class="std std-ref">printf 风格的字符串格式化</span></a> 一节。</p>
<p>整除运算符，模运算符和 <a class="reference internal" href="../library/functions.html#divmod" title="divmod"><code class="xref py py-func docutils literal notranslate"><span class="pre">divmod()</span></code></a> 函数未被定义用于复数。 如果有必要可以使用 <a class="reference internal" href="../library/functions.html#abs" title="abs"><code class="xref py py-func docutils literal notranslate"><span class="pre">abs()</span></code></a> 函数将其转换为浮点数。</p>
<p id="index-67">运算符 <code class="docutils literal notranslate"><span class="pre">+</span></code> (addition) 将输出其参数的和。 两个参数或者必须都为数字，或者都为相同类型的序列。 在前一种情况下，两个数字将被转换为相同类型然后相加。 在后一种情况下，将执行序列拼接操作。</p>
<p id="index-68">运算符 <code class="docutils literal notranslate"><span class="pre">-</span></code> (减) 将输出其参数的差。 两个数字参数将先被转换为相同类型。</p>
</div>
<div class="section" id="shifting-operations">
<span id="shifting"></span><h2><span class="section-number">6.8. </span>移位运算<a class="headerlink" href="#shifting-operations" title="永久链接至标题">¶</a></h2>
<p id="index-69">移位运算的优先级低于算术运算:</p>
<pre>
<strong id="grammar-token-shift-expr">shift_expr</strong> ::=  <a class="reference internal" href="#grammar-token-a-expr"><code class="xref docutils literal notranslate"><span class="pre">a_expr</span></code></a> | <a class="reference internal" href="#grammar-token-shift-expr"><code class="xref docutils literal notranslate"><span class="pre">shift_expr</span></code></a> (&quot;&lt;&lt;&quot; | &quot;&gt;&gt;&quot;) <a class="reference internal" href="#grammar-token-a-expr"><code class="xref docutils literal notranslate"><span class="pre">a_expr</span></code></a>
</pre>
<p>这些运算符接受整数参数。 它们会将第一个参数左移或右移第二个参数所指定的比特位数。</p>
<p id="index-70">右移 <em>n</em> 位被定义为被 <code class="docutils literal notranslate"><span class="pre">pow(2,n)</span></code> 整除。 左移 <em>n</em> 位被定义为乘以 <code class="docutils literal notranslate"><span class="pre">pow(2,n)</span></code>。</p>
</div>
<div class="section" id="binary-bitwise-operations">
<span id="bitwise"></span><h2><span class="section-number">6.9. </span>二元位运算<a class="headerlink" href="#binary-bitwise-operations" title="永久链接至标题">¶</a></h2>
<p id="index-71">三种位运算具有各不相同的优先级:</p>
<pre>
<strong id="grammar-token-and-expr">and_expr</strong> ::=  <a class="reference internal" href="#grammar-token-shift-expr"><code class="xref docutils literal notranslate"><span class="pre">shift_expr</span></code></a> | <a class="reference internal" href="#grammar-token-and-expr"><code class="xref docutils literal notranslate"><span class="pre">and_expr</span></code></a> &quot;&amp;&quot; <a class="reference internal" href="#grammar-token-shift-expr"><code class="xref docutils literal notranslate"><span class="pre">shift_expr</span></code></a>
<strong id="grammar-token-xor-expr">xor_expr</strong> ::=  <a class="reference internal" href="#grammar-token-and-expr"><code class="xref docutils literal notranslate"><span class="pre">and_expr</span></code></a> | <a class="reference internal" href="#grammar-token-xor-expr"><code class="xref docutils literal notranslate"><span class="pre">xor_expr</span></code></a> &quot;^&quot; <a class="reference internal" href="#grammar-token-and-expr"><code class="xref docutils literal notranslate"><span class="pre">and_expr</span></code></a>
<strong id="grammar-token-or-expr">or_expr </strong> ::=  <a class="reference internal" href="#grammar-token-xor-expr"><code class="xref docutils literal notranslate"><span class="pre">xor_expr</span></code></a> | <a class="reference internal" href="#grammar-token-or-expr"><code class="xref docutils literal notranslate"><span class="pre">or_expr</span></code></a> &quot;|&quot; <a class="reference internal" href="#grammar-token-xor-expr"><code class="xref docutils literal notranslate"><span class="pre">xor_expr</span></code></a>
</pre>
<p id="index-72">运算符 <code class="docutils literal notranslate"><span class="pre">&amp;</span></code> 对两个参数进行按位 AND (与) 运算，两个参数必须为整数。</p>
<p id="index-73">运算符 <code class="docutils literal notranslate"><span class="pre">^</span></code> 对两个参数进行按位 XOR (异或) 运算，两个参数必须为整数。</p>
<p id="index-74">运算符 <code class="docutils literal notranslate"><span class="pre">|</span></code> 对两个参数进行按位 OR (或) 运算，两个参数必须为整数。</p>
</div>
<div class="section" id="comparisons">
<span id="id11"></span><h2><span class="section-number">6.10. </span>比较运算<a class="headerlink" href="#comparisons" title="永久链接至标题">¶</a></h2>
<p id="index-75">与 C 不同，Python 中所有比较运算的优先级相同，低于任何算术、移位或位运算。 另一个与 C 不同之处在于 <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">&lt;</span> <span class="pre">b</span> <span class="pre">&lt;</span> <span class="pre">c</span></code> 这样的表达式会按传统算术法则来解读:</p>
<pre>
<strong id="grammar-token-comparison">comparison   </strong> ::=  <a class="reference internal" href="#grammar-token-or-expr"><code class="xref docutils literal notranslate"><span class="pre">or_expr</span></code></a> (<a class="reference internal" href="#grammar-token-comp-operator"><code class="xref docutils literal notranslate"><span class="pre">comp_operator</span></code></a> <a class="reference internal" href="#grammar-token-or-expr"><code class="xref docutils literal notranslate"><span class="pre">or_expr</span></code></a>)*
<strong id="grammar-token-comp-operator">comp_operator</strong> ::=  &quot;&lt;&quot; | &quot;&gt;&quot; | &quot;==&quot; | &quot;&gt;=&quot; | &quot;&lt;=&quot; | &quot;!=&quot;
                   | &quot;is&quot; [&quot;not&quot;] | [&quot;not&quot;] &quot;in&quot;
</pre>
<p>比较运算将输出布尔值: <code class="docutils literal notranslate"><span class="pre">True</span></code> 或 <code class="docutils literal notranslate"><span class="pre">False</span></code>。</p>
<p id="index-76">比较运算可以任意串连，例如 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&lt;</span> <span class="pre">y</span> <span class="pre">&lt;=</span> <span class="pre">z</span></code> 等价于 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&lt;</span> <span class="pre">y</span> <span class="pre">and</span> <span class="pre">y</span> <span class="pre">&lt;=</span> <span class="pre">z</span></code>，除了 <code class="docutils literal notranslate"><span class="pre">y</span></code> 只被求值一次（但在两种写法下当 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&lt;</span> <span class="pre">y</span></code> 值为假时 <code class="docutils literal notranslate"><span class="pre">z</span></code> 都不会被求值）。</p>
<p>正式的说法是这样：如果 <em>a</em>, <em>b</em>, <em>c</em>, ..., <em>y</em>, <em>z</em> 为表达式而 <em>op1</em>, <em>op2</em>, ..., <em>opN</em> 为比较运算符，则 <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">op1</span> <span class="pre">b</span> <span class="pre">op2</span> <span class="pre">c</span> <span class="pre">...</span> <span class="pre">y</span> <span class="pre">opN</span> <span class="pre">z</span></code> 就等价于 <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">op1</span> <span class="pre">b</span> <span class="pre">and</span> <span class="pre">b</span> <span class="pre">op2</span> <span class="pre">c</span> <span class="pre">and</span> <span class="pre">...</span> <span class="pre">y</span> <span class="pre">opN</span> <span class="pre">z</span></code>，后者的不同之处只是每个表达式最多只被求值一次。</p>
<p>请注意 <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">op1</span> <span class="pre">b</span> <span class="pre">op2</span> <span class="pre">c</span></code> 不意味着在 <em>a</em> 和 <em>c</em> 之间进行任何比较，因此，如 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&lt;</span> <span class="pre">y</span> <span class="pre">&gt;</span> <span class="pre">z</span></code> 这样的写法是完全合法的（虽然也许不太好看）。</p>
<div class="section" id="value-comparisons">
<h3><span class="section-number">6.10.1. </span>值比较<a class="headerlink" href="#value-comparisons" title="永久链接至标题">¶</a></h3>
<p>运算符 <code class="docutils literal notranslate"><span class="pre">&lt;</span></code>, <code class="docutils literal notranslate"><span class="pre">&gt;</span></code>, <code class="docutils literal notranslate"><span class="pre">==</span></code>, <code class="docutils literal notranslate"><span class="pre">&gt;=</span></code>, <code class="docutils literal notranslate"><span class="pre">&lt;=</span></code> 和 <code class="docutils literal notranslate"><span class="pre">!=</span></code> 将比较两个对象的值。 两个对象不要求为相同类型。</p>
<p><a class="reference internal" href="datamodel.html#objects"><span class="std std-ref">对象、值与类型</span></a> 一章已说明对象都有相应的值（还有类型和标识号）。 对象值在 Python 中是一个相当抽象的概念：例如，对象值并没有一个规范的访问方法。 而且，对象值并不要求具有特定的构建方式，例如由其全部数据属性组成等。 比较运算符实现了一个特定的对象值概念。 人们可以认为这是通过实现对象比较间接地定义了对象值。</p>
<p>由于所有类型都是 <a class="reference internal" href="../library/functions.html#object" title="object"><code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></a> 的（直接或间接）子类型，它们都从 <a class="reference internal" href="../library/functions.html#object" title="object"><code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></a> 继承了默认的比较行为。 类型可以通过实现 <em class="dfn">丰富比较方法</em> 例如 <a class="reference internal" href="datamodel.html#object.__lt__" title="object.__lt__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__lt__()</span></code></a> 来定义自己的比较行为，详情参见 <a class="reference internal" href="datamodel.html#customization"><span class="std std-ref">基本定制</span></a>。</p>
<p>默认的一致性比较 (<code class="docutils literal notranslate"><span class="pre">==</span></code> 和 <code class="docutils literal notranslate"><span class="pre">!=</span></code>) 是基于对象的标识号。 因此，具有相同标识号的实例一致性比较结果为相等，具有不同标识号的实例一致性比较结果为不等。 规定这种默认行为的动机是希望所有对象都应该是自反射的 (即 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">is</span> <span class="pre">y</span></code> 就意味着 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">y</span></code>)。</p>
<p>次序比较 (<code class="docutils literal notranslate"><span class="pre">&lt;</span></code>, <code class="docutils literal notranslate"><span class="pre">&gt;</span></code>, <code class="docutils literal notranslate"><span class="pre">&lt;=</span></code> 和 <code class="docutils literal notranslate"><span class="pre">&gt;=</span></code>) 默认没有提供；如果尝试比较会引发 <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a>。 规定这种默认行为的原因是缺少与一致性比较类似的固定值。</p>
<p>按照默认的一致性比较行为，具有不同标识号的实例总是不相等，这可能不适合某些对象值需要有合理定义并有基于值的一致性的类型。 这样的类型需要定制自己的比较行为，实际上，许多内置类型都是这样做的。</p>
<p>以下列表描述了最主要内置类型的比较行为。</p>
<ul>
<li><p>内置数值类型 (<a class="reference internal" href="../library/stdtypes.html#typesnumeric"><span class="std std-ref">数字类型 --- int, float, complex</span></a>) 以及标准库类型 <a class="reference internal" href="../library/fractions.html#fractions.Fraction" title="fractions.Fraction"><code class="xref py py-class docutils literal notranslate"><span class="pre">fractions.Fraction</span></code></a> 和 <a class="reference internal" href="../library/decimal.html#decimal.Decimal" title="decimal.Decimal"><code class="xref py py-class docutils literal notranslate"><span class="pre">decimal.Decimal</span></code></a> 可进行类型内部和跨类型的比较，例外限制是复数不支持次序比较。 在类型相关的限制以内，它们会按数学（算法）规则正确进行比较且不会有精度损失。</p>
<p>非数字值 <code class="docutils literal notranslate"><span class="pre">float('NaN')</span></code> 和 <code class="docutils literal notranslate"><span class="pre">decimal.Decimal('NaN')</span></code> 属于特例。 任何数字与非数字值的排序比较均返回假值。 还有一个反直觉的结果是非数字值不等于其自身。 举例来说，如果 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">=</span> <span class="pre">float('NaN')</span></code> 则 <code class="docutils literal notranslate"><span class="pre">3</span> <span class="pre">&lt;</span> <span class="pre">x</span></code>, <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&lt;</span> <span class="pre">3</span></code> 和 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">x</span></code> 均为假值，而 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">!=</span> <span class="pre">x</span></code> 则为真值。 此行为是遵循 IEEE 754 标准的。</p>
</li>
<li><p>二进制码序列 (<a class="reference internal" href="../library/stdtypes.html#bytes" title="bytes"><code class="xref py py-class docutils literal notranslate"><span class="pre">bytes</span></code></a> 或 <a class="reference internal" href="../library/stdtypes.html#bytearray" title="bytearray"><code class="xref py py-class docutils literal notranslate"><span class="pre">bytearray</span></code></a> 的实例) 可进行类型内部和跨类型的比较。 它们使用其元素的数字值按字典顺序进行比较。</p></li>
<li><p>字符串 (<a class="reference internal" href="../library/stdtypes.html#str" title="str"><code class="xref py py-class docutils literal notranslate"><span class="pre">str</span></code></a> 的实例) 使用其字符的 Unicode 码位数字值 (内置函数 <a class="reference internal" href="../library/functions.html#ord" title="ord"><code class="xref py py-func docutils literal notranslate"><span class="pre">ord()</span></code></a> 的结果) 按字典顺序进行比较。 <a class="footnote-reference brackets" href="#id19" id="id12">3</a></p>
<p>字符串和二进制码序列不能直接比较。</p>
</li>
<li><p>序列 (<a class="reference internal" href="../library/stdtypes.html#tuple" title="tuple"><code class="xref py py-class docutils literal notranslate"><span class="pre">tuple</span></code></a>, <a class="reference internal" href="../library/stdtypes.html#list" title="list"><code class="xref py py-class docutils literal notranslate"><span class="pre">list</span></code></a> 或 <a class="reference internal" href="../library/stdtypes.html#range" title="range"><code class="xref py py-class docutils literal notranslate"><span class="pre">range</span></code></a> 的实例) 只可进行类型内部的比较，range 还有一个限制是不支持次序比较。 以上对象的跨类型一致性比较结果将是不相等，跨类型次序比较将引发 <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a>。</p>
<p>序列通过相应元素的比较进行字典列比较，并强制规定元素自反射性。</p>
<p>由于强制元素自反射性，多项集的比较将假定对于一个多项集元素 <code class="docutils literal notranslate"><span class="pre">x</span></code>, <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">x</span></code> 总是为真。 基于该假设，将首先比较元素标识号，并且仅会对不同元素执行元素比较。 如果元素是自反射的，这种方式会产生与严格元素比较相同的结果。 对于非自反射的元素，结果将不同于严格元素比较，并且可能会令人惊讶：例如当在列表中使用非自反射的非数字值时，将导致以下比较行为:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">nan</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="s1">&#39;NaN&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">nan</span> <span class="ow">is</span> <span class="n">nan</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">nan</span> <span class="o">==</span> <span class="n">nan</span>
<span class="go">False                 &lt;-- the defined non-reflexive behavior of NaN</span>
<span class="gp">&gt;&gt;&gt; </span><span class="p">[</span><span class="n">nan</span><span class="p">]</span> <span class="o">==</span> <span class="p">[</span><span class="n">nan</span><span class="p">]</span>
<span class="go">True                  &lt;-- list enforces reflexivity and tests identity first</span>
</pre></div>
</div>
<p>内置多项集间的字典序比较规则如下:</p>
<ul class="simple">
<li><p>两个多项集若要相等，它们必须为相同类型、相同长度，并且每对相应的元素都必须相等（例如，<code class="docutils literal notranslate"><span class="pre">[1,2]</span> <span class="pre">==</span> <span class="pre">(1,2)</span></code> 为假值，因为类型不同）。</p></li>
<li><p>对于支持次序比较的多项集，排序与其第一个不相等元素的排序相同（例如 <code class="docutils literal notranslate"><span class="pre">[1,2,x]</span> <span class="pre">&lt;=</span> <span class="pre">[1,2,y]</span></code> 的值与``x &lt;= y`` 相同）。 如果对应元素不存在，较短的多项集排序在前（例如 <code class="docutils literal notranslate"><span class="pre">[1,2]</span> <span class="pre">&lt;</span> <span class="pre">[1,2,3]</span></code> 为真值）。</p></li>
</ul>
</li>
<li><p>两个映射 (<a class="reference internal" href="../library/stdtypes.html#dict" title="dict"><code class="xref py py-class docutils literal notranslate"><span class="pre">dict</span></code></a> 的实例) 若要相等，必须当且仅当它们具有相同的 <cite>(键, 值)</cite> 对。 键和值的一致性比较强制规定自反射性。</p>
<p>次序比较 (<code class="docutils literal notranslate"><span class="pre">&lt;</span></code>, <code class="docutils literal notranslate"><span class="pre">&gt;</span></code>, <code class="docutils literal notranslate"><span class="pre">&lt;=</span></code> 和 <code class="docutils literal notranslate"><span class="pre">&gt;=</span></code>) 将引发 <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a>。</p>
</li>
<li><p>集合 (<a class="reference internal" href="../library/stdtypes.html#set" title="set"><code class="xref py py-class docutils literal notranslate"><span class="pre">set</span></code></a> 或 <a class="reference internal" href="../library/stdtypes.html#frozenset" title="frozenset"><code class="xref py py-class docutils literal notranslate"><span class="pre">frozenset</span></code></a> 的实例) 可进行类型内部和跨类型的比较。</p>
<p>它们将比较运算符定义为子集和超集检测。 这类关系没有定义完全排序（例如 <code class="docutils literal notranslate"><span class="pre">{1,2}</span></code> 和 <code class="docutils literal notranslate"><span class="pre">{2,3}</span></code> 两个集合不相等，即不为彼此的子集，也不为彼此的超集。 相应地，集合不适宜作为依赖于完全排序的函数的参数（例如如果给出一个集合列表作为 <a class="reference internal" href="../library/functions.html#min" title="min"><code class="xref py py-func docutils literal notranslate"><span class="pre">min()</span></code></a>, <a class="reference internal" href="../library/functions.html#max" title="max"><code class="xref py py-func docutils literal notranslate"><span class="pre">max()</span></code></a> 和 <a class="reference internal" href="../library/functions.html#sorted" title="sorted"><code class="xref py py-func docutils literal notranslate"><span class="pre">sorted()</span></code></a> 的输入将产生未定义的结果）。</p>
<p>集合的比较强制规定其元素的自反射性。</p>
</li>
<li><p>大多数其他内置类型没有实现比较方法，因此它们会继承默认的比较行为。</p></li>
</ul>
<p>在可能的情况下，用户定义类在定制其比较行为时应当遵循一些一致性规则:</p>
<ul>
<li><p>相等比较应该是自反射的。 换句话说，相同的对象比较时应该相等:</p>
<blockquote>
<div><p><code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">is</span> <span class="pre">y</span></code> 意味着 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">y</span></code></p>
</div></blockquote>
</li>
<li><p>比较应该是对称的。 换句话说，下列表达式应该有相同的结果:</p>
<blockquote>
<div><p><code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">y</span></code> 和 <code class="docutils literal notranslate"><span class="pre">y</span> <span class="pre">==</span> <span class="pre">x</span></code></p>
<p><code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">!=</span> <span class="pre">y</span></code> 和 <code class="docutils literal notranslate"><span class="pre">y</span> <span class="pre">!=</span> <span class="pre">x</span></code></p>
<p><code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&lt;</span> <span class="pre">y</span></code> 和 <code class="docutils literal notranslate"><span class="pre">y</span> <span class="pre">&gt;</span> <span class="pre">x</span></code></p>
<p><code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&lt;=</span> <span class="pre">y</span></code> 和 <code class="docutils literal notranslate"><span class="pre">y</span> <span class="pre">&gt;=</span> <span class="pre">x</span></code></p>
</div></blockquote>
</li>
<li><p>比较应该是可传递的。 下列（简要的）例子显示了这一点:</p>
<blockquote>
<div><p><code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&gt;</span> <span class="pre">y</span> <span class="pre">and</span> <span class="pre">y</span> <span class="pre">&gt;</span> <span class="pre">z</span></code> 意味着 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&gt;</span> <span class="pre">z</span></code></p>
<p><code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&lt;</span> <span class="pre">y</span> <span class="pre">and</span> <span class="pre">y</span> <span class="pre">&lt;=</span> <span class="pre">z</span></code> 意味着 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&lt;</span> <span class="pre">z</span></code></p>
</div></blockquote>
</li>
<li><p>反向比较应该导致布尔值取反。 换句话说，下列表达式应该有相同的结果:</p>
<blockquote>
<div><p><code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">==</span> <span class="pre">y</span></code> 和 <code class="docutils literal notranslate"><span class="pre">not</span> <span class="pre">x</span> <span class="pre">!=</span> <span class="pre">y</span></code></p>
<p><code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&lt;</span> <span class="pre">y</span></code> 和 <code class="docutils literal notranslate"><span class="pre">not</span> <span class="pre">x</span> <span class="pre">&gt;=</span> <span class="pre">y</span></code> (对于完全排序)</p>
<p><code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">&gt;</span> <span class="pre">y</span></code> 和 <code class="docutils literal notranslate"><span class="pre">not</span> <span class="pre">x</span> <span class="pre">&lt;=</span> <span class="pre">y</span></code> (对于完全排序)</p>
</div></blockquote>
<p>最后两个表达式适用于完全排序的多项集（即序列而非集合或映射）。 另请参阅 <a class="reference internal" href="../library/functools.html#functools.total_ordering" title="functools.total_ordering"><code class="xref py py-func docutils literal notranslate"><span class="pre">total_ordering()</span></code></a> 装饰器。</p>
</li>
<li><p><a class="reference internal" href="../library/functions.html#hash" title="hash"><code class="xref py py-func docutils literal notranslate"><span class="pre">hash()</span></code></a> 的结果应该与是否相等一致。 相等的对象应该或者具有相同的哈希值，或者标记为不可哈希。</p></li>
</ul>
<p>Python 并不强制要求这些一致性规则。 实际上，非数字值就是一个不遵循这些规则的例子。</p>
</div>
<div class="section" id="membership-test-operations">
<span id="membership-test-details"></span><span id="not-in"></span><span id="in"></span><h3><span class="section-number">6.10.2. </span>成员检测运算<a class="headerlink" href="#membership-test-operations" title="永久链接至标题">¶</a></h3>
<p>运算符 <a class="reference internal" href="#in"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">in</span></code></a> 和 <a class="reference internal" href="#not-in"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">not</span> <span class="pre">in</span></code></a> 用于成员检测。 如果 <em>x</em> 是 <em>s</em> 的成员则 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">in</span> <span class="pre">s</span></code> 求值为 <code class="docutils literal notranslate"><span class="pre">True</span></code>，否则为 <code class="docutils literal notranslate"><span class="pre">False</span></code>。 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">not</span> <span class="pre">in</span> <span class="pre">s</span></code> 返回 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">in</span> <span class="pre">s</span></code> 取反后的值。 所有内置序列和集合类型以及字典都支持此运算，对于字典来说 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">in</span></code> 检测其是否有给定的键。 对于 list, tuple, set, frozenset, dict 或 collections.deque 这样的容器类型，表达式 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">in</span> <span class="pre">y</span></code> 等价于 <code class="docutils literal notranslate"><span class="pre">any(x</span> <span class="pre">is</span> <span class="pre">e</span> <span class="pre">or</span> <span class="pre">x</span> <span class="pre">==</span> <span class="pre">e</span> <span class="pre">for</span> <span class="pre">e</span> <span class="pre">in</span> <span class="pre">y)</span></code>。</p>
<p>对于字符串和字节串类型来说，当且仅当 <em>x</em> 是 <em>y</em> 的子串时 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">in</span> <span class="pre">y</span></code> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code>。 一个等价的检测是 <code class="docutils literal notranslate"><span class="pre">y.find(x)</span> <span class="pre">!=</span> <span class="pre">-1</span></code>。 空字符串总是被视为任何其他字符串的子串，因此 <code class="docutils literal notranslate"><span class="pre">&quot;&quot;</span> <span class="pre">in</span> <span class="pre">&quot;abc&quot;</span></code> 将返回 <code class="docutils literal notranslate"><span class="pre">True</span></code>。</p>
<p>对于定义了 <a class="reference internal" href="datamodel.html#object.__contains__" title="object.__contains__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__contains__()</span></code></a> 方法的用户自定义类来说，如果 <code class="docutils literal notranslate"><span class="pre">y.__contains__(x)</span></code> 返回真值则 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">in</span> <span class="pre">y</span></code> 返回 <code class="docutils literal notranslate"><span class="pre">True</span></code>，否则返回 <code class="docutils literal notranslate"><span class="pre">False</span></code>。</p>
<p>对于未定义 <a class="reference internal" href="datamodel.html#object.__contains__" title="object.__contains__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__contains__()</span></code></a> 但定义了 <a class="reference internal" href="datamodel.html#object.__iter__" title="object.__iter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__iter__()</span></code></a> 的用户自定义类来说，如果在对 <code class="docutils literal notranslate"><span class="pre">y</span></code> 进行迭代时产生了值 <code class="docutils literal notranslate"><span class="pre">z</span></code> 使得表达式 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">is</span> <span class="pre">z</span> <span class="pre">or</span> <span class="pre">x</span> <span class="pre">==</span> <span class="pre">z</span></code> 为真，则 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">in</span> <span class="pre">y</span></code> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code>。 如果在迭代期间引发了异常，则等同于 <a class="reference internal" href="#in"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">in</span></code></a> 引发了该异常。</p>
<p>最后将会尝试旧式的迭代协议：如果一个类定义了 <a class="reference internal" href="datamodel.html#object.__getitem__" title="object.__getitem__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__getitem__()</span></code></a>，则当且仅当存在非负整数索引号 <em>i</em> 使得 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">is</span> <span class="pre">y[i]</span> <span class="pre">or</span> <span class="pre">x</span> <span class="pre">==</span> <span class="pre">y[i]</span></code> 并且没有更小的索引号引发 <a class="reference internal" href="../library/exceptions.html#IndexError" title="IndexError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">IndexError</span></code></a> 异常时 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">in</span> <span class="pre">y</span></code> 为 <code class="docutils literal notranslate"><span class="pre">True</span></code>。 （如果引发了任何其他异常，则等同于 <a class="reference internal" href="#in"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">in</span></code></a> 引发了该异常）。</p>
<p id="index-77">运算符 <a class="reference internal" href="#not-in"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">not</span> <span class="pre">in</span></code></a> 被定义为具有与 <a class="reference internal" href="#in"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">in</span></code></a> 相反的逻辑值。</p>
</div>
<div class="section" id="is-not">
<span id="is"></span><span id="index-78"></span><span id="identity-comparisons"></span><h3><span class="section-number">6.10.3. </span>标识号比较<a class="headerlink" href="#is-not" title="永久链接至标题">¶</a></h3>
<p>运算符 <a class="reference internal" href="#is"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">is</span></code></a> 和 <a class="reference internal" href="#is-not"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">is</span> <span class="pre">not</span></code></a> 用于检测对象的标识号：当且仅当 <em>x</em> 和 <em>y</em> 是同一对象时 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">is</span> <span class="pre">y</span></code> 为真。 一个对象的标识号可使用 <a class="reference internal" href="../library/functions.html#id" title="id"><code class="xref py py-meth docutils literal notranslate"><span class="pre">id()</span></code></a> 函数来确定。 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">is</span> <span class="pre">not</span> <span class="pre">y</span></code> 会产生相反的逻辑值。 <a class="footnote-reference brackets" href="#id20" id="id13">4</a></p>
</div>
</div>
<div class="section" id="boolean-operations">
<span id="not"></span><span id="or"></span><span id="and"></span><span id="booleans"></span><h2><span class="section-number">6.11. </span>布尔运算<a class="headerlink" href="#boolean-operations" title="永久链接至标题">¶</a></h2>
<pre id="index-79">
<strong id="grammar-token-or-test">or_test </strong> ::=  <a class="reference internal" href="#grammar-token-and-test"><code class="xref docutils literal notranslate"><span class="pre">and_test</span></code></a> | <a class="reference internal" href="#grammar-token-or-test"><code class="xref docutils literal notranslate"><span class="pre">or_test</span></code></a> &quot;or&quot; <a class="reference internal" href="#grammar-token-and-test"><code class="xref docutils literal notranslate"><span class="pre">and_test</span></code></a>
<strong id="grammar-token-and-test">and_test</strong> ::=  <a class="reference internal" href="#grammar-token-not-test"><code class="xref docutils literal notranslate"><span class="pre">not_test</span></code></a> | <a class="reference internal" href="#grammar-token-and-test"><code class="xref docutils literal notranslate"><span class="pre">and_test</span></code></a> &quot;and&quot; <a class="reference internal" href="#grammar-token-not-test"><code class="xref docutils literal notranslate"><span class="pre">not_test</span></code></a>
<strong id="grammar-token-not-test">not_test</strong> ::=  <a class="reference internal" href="#grammar-token-comparison"><code class="xref docutils literal notranslate"><span class="pre">comparison</span></code></a> | &quot;not&quot; <a class="reference internal" href="#grammar-token-not-test"><code class="xref docutils literal notranslate"><span class="pre">not_test</span></code></a>
</pre>
<p>在执行布尔运算的情况下，或是当表达式被用于流程控制语句时，以下值会被解析为假值: <code class="docutils literal notranslate"><span class="pre">False</span></code>, <code class="docutils literal notranslate"><span class="pre">None</span></code>, 所有类型的数字零，以及空字符串和空容器（包括字符串、元组、列表、字典、集合与冻结集合）。 所有其他值都会被解析为真值。 用户自定义对象可通过提供 <a class="reference internal" href="datamodel.html#object.__bool__" title="object.__bool__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__bool__()</span></code></a> 方法来定制其逻辑值。</p>
<p id="index-80">运算符 <a class="reference internal" href="#not"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">not</span></code></a> 将在其参数为假值时产生 <code class="docutils literal notranslate"><span class="pre">True</span></code>，否则产生 <code class="docutils literal notranslate"><span class="pre">False</span></code>。</p>
<p id="index-81">表达式 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">and</span> <span class="pre">y</span></code> 首先对 <em>x</em> 求值；如果 <em>x</em> 为假则返回该值；否则对 <em>y</em> 求值并返回其结果值。</p>
<p id="index-82">表达式 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">or</span> <span class="pre">y</span></code> 首先对 <em>x</em> 求值；如果 <em>x</em> 为真则返回该值；否则对 <em>y</em> 求值并返回其结果值。</p>
<p>请注意 <a class="reference internal" href="#and"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">and</span></code></a> 和 <a class="reference internal" href="#or"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">or</span></code></a> 都不限制其返回的值和类型必须为 <code class="docutils literal notranslate"><span class="pre">False</span></code> 和 <code class="docutils literal notranslate"><span class="pre">True</span></code>，而是返回最终求值的参数。 此行为是有必要的，例如假设 <code class="docutils literal notranslate"><span class="pre">s</span></code> 为一个当其为空时应被替换为某个默认值的字符串，表达式 <code class="docutils literal notranslate"><span class="pre">s</span> <span class="pre">or</span> <span class="pre">'foo'</span></code> 将产生希望的值。 由于 <a class="reference internal" href="#not"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">not</span></code></a> 必须创建一个新值，不论其参数为何种类型它都会返回一个布尔值（例如，<code class="docutils literal notranslate"><span class="pre">not</span> <span class="pre">'foo'</span></code> 结果为 <code class="docutils literal notranslate"><span class="pre">False</span></code> 而非 <code class="docutils literal notranslate"><span class="pre">''</span></code>。）</p>
</div>
<div class="section" id="conditional-expressions">
<span id="if-expr"></span><h2><span class="section-number">6.12. </span>条件表达式<a class="headerlink" href="#conditional-expressions" title="永久链接至标题">¶</a></h2>
<pre id="index-83">
<strong id="grammar-token-conditional-expression">conditional_expression</strong> ::=  <a class="reference internal" href="#grammar-token-or-test"><code class="xref docutils literal notranslate"><span class="pre">or_test</span></code></a> [&quot;if&quot; <a class="reference internal" href="#grammar-token-or-test"><code class="xref docutils literal notranslate"><span class="pre">or_test</span></code></a> &quot;else&quot; <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>]
<strong id="grammar-token-expression">expression            </strong> ::=  <a class="reference internal" href="#grammar-token-conditional-expression"><code class="xref docutils literal notranslate"><span class="pre">conditional_expression</span></code></a> | <a class="reference internal" href="#grammar-token-lambda-expr"><code class="xref docutils literal notranslate"><span class="pre">lambda_expr</span></code></a>
<strong id="grammar-token-expression-nocond">expression_nocond     </strong> ::=  <a class="reference internal" href="#grammar-token-or-test"><code class="xref docutils literal notranslate"><span class="pre">or_test</span></code></a> | <a class="reference internal" href="#grammar-token-lambda-expr-nocond"><code class="xref docutils literal notranslate"><span class="pre">lambda_expr_nocond</span></code></a>
</pre>
<p>条件表达式（有时称为“三元运算符”）在所有 Python 运算中具有最低的优先级。</p>
<p>表达式 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">if</span> <span class="pre">C</span> <span class="pre">else</span> <span class="pre">y</span></code> 首先是对条件 <em>C</em> 而非 <em>x</em> 求值。 如果 <em>C</em> 为真，<em>x</em> 将被求值并返回其值；否则将对 <em>y</em> 求值并返回其值。</p>
<p>请参阅 <span class="target" id="index-111"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0308"><strong>PEP 308</strong></a> 了解有关条件表达式的详情。</p>
</div>
<div class="section" id="lambda">
<span id="lambdas"></span><span id="id14"></span><h2><span class="section-number">6.13. </span>lambda 表达式<a class="headerlink" href="#lambda" title="永久链接至标题">¶</a></h2>
<pre id="index-85">
<strong id="grammar-token-lambda-expr">lambda_expr       </strong> ::=  &quot;lambda&quot; [<a class="reference internal" href="compound_stmts.html#grammar-token-parameter-list"><code class="xref docutils literal notranslate"><span class="pre">parameter_list</span></code></a>] &quot;:&quot; <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>
<strong id="grammar-token-lambda-expr-nocond">lambda_expr_nocond</strong> ::=  &quot;lambda&quot; [<a class="reference internal" href="compound_stmts.html#grammar-token-parameter-list"><code class="xref docutils literal notranslate"><span class="pre">parameter_list</span></code></a>] &quot;:&quot; <a class="reference internal" href="#grammar-token-expression-nocond"><code class="xref docutils literal notranslate"><span class="pre">expression_nocond</span></code></a>
</pre>
<p>lambda 表达式（有时称为 lambda 构型）被用于创建匿名函数。 表达式 <code class="docutils literal notranslate"><span class="pre">lambda</span> <span class="pre">parameters:</span> <span class="pre">expression</span></code> 会产生一个函数对象 。 该未命名对象的行为类似于用以下方式定义的函数:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>def &lt;lambda&gt;(parameters):
    return expression
</pre></div>
</div>
<p>请参阅 <a class="reference internal" href="compound_stmts.html#function"><span class="std std-ref">函数定义</span></a> 了解有关参数列表的句法。 请注意通过 lambda 表达式创建的函数不能包含语句或标注。</p>
</div>
<div class="section" id="expression-lists">
<span id="exprlists"></span><h2><span class="section-number">6.14. </span>表达式列表<a class="headerlink" href="#expression-lists" title="永久链接至标题">¶</a></h2>
<pre id="index-86">
<strong id="grammar-token-expression-list">expression_list   </strong> ::=  <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> (&quot;,&quot; <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>)* [&quot;,&quot;]
<strong id="grammar-token-starred-list">starred_list      </strong> ::=  <a class="reference internal" href="#grammar-token-starred-item"><code class="xref docutils literal notranslate"><span class="pre">starred_item</span></code></a> (&quot;,&quot; <a class="reference internal" href="#grammar-token-starred-item"><code class="xref docutils literal notranslate"><span class="pre">starred_item</span></code></a>)* [&quot;,&quot;]
<strong id="grammar-token-starred-expression">starred_expression</strong> ::=  <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> | (<a class="reference internal" href="#grammar-token-starred-item"><code class="xref docutils literal notranslate"><span class="pre">starred_item</span></code></a> &quot;,&quot;)* [<a class="reference internal" href="#grammar-token-starred-item"><code class="xref docutils literal notranslate"><span class="pre">starred_item</span></code></a>]
<strong id="grammar-token-starred-item">starred_item      </strong> ::=  <a class="reference internal" href="#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> | &quot;*&quot; <a class="reference internal" href="#grammar-token-or-expr"><code class="xref docutils literal notranslate"><span class="pre">or_expr</span></code></a>
</pre>
<p id="index-87">除了作为列表或集合显示的一部分，包含至少一个逗号的表达式列表将生成一个元组。 元组的长度就是列表中表达式的数量。 表达式将从左至右被求值。</p>
<p id="index-88">一个星号 <code class="docutils literal notranslate"><span class="pre">*</span></code> 表示 <em class="dfn">可迭代拆包</em>。 其操作数必须为一个 <a class="reference internal" href="../glossary.html#term-iterable"><span class="xref std std-term">iterable</span></a>。 该可迭代对象将被拆解为迭代项的序列，并被包含于在拆包位置上新建的元组、列表或集合之中。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.5 新版功能: </span>表达式列表中的可迭代对象拆包，最初由 <span class="target" id="index-112"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0448"><strong>PEP 448</strong></a> 提出。</p>
</div>
<p id="index-90">末尾的逗号仅在创建单独元组 (或称 <em>单例</em>) 时需要；在所有其他情况下都是可选项。 没有末尾逗号的单独表达式不会创建一个元组，而是产生该表达式的值。 （要创建一个空元组，应使用一对内容为空的圆括号: <code class="docutils literal notranslate"><span class="pre">()</span></code>。）</p>
</div>
<div class="section" id="evaluation-order">
<span id="evalorder"></span><h2><span class="section-number">6.15. </span>求值顺序<a class="headerlink" href="#evaluation-order" title="永久链接至标题">¶</a></h2>
<p id="index-91">Python 按从左至右的顺序对表达式求值。 但注意在对赋值操作求值时，右侧会先于左侧被求值。</p>
<p>在以下几行中，表达式将按其后缀的算术优先顺序被求值。:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">expr1</span><span class="p">,</span> <span class="n">expr2</span><span class="p">,</span> <span class="n">expr3</span><span class="p">,</span> <span class="n">expr4</span>
<span class="p">(</span><span class="n">expr1</span><span class="p">,</span> <span class="n">expr2</span><span class="p">,</span> <span class="n">expr3</span><span class="p">,</span> <span class="n">expr4</span><span class="p">)</span>
<span class="p">{</span><span class="n">expr1</span><span class="p">:</span> <span class="n">expr2</span><span class="p">,</span> <span class="n">expr3</span><span class="p">:</span> <span class="n">expr4</span><span class="p">}</span>
<span class="n">expr1</span> <span class="o">+</span> <span class="n">expr2</span> <span class="o">*</span> <span class="p">(</span><span class="n">expr3</span> <span class="o">-</span> <span class="n">expr4</span><span class="p">)</span>
<span class="n">expr1</span><span class="p">(</span><span class="n">expr2</span><span class="p">,</span> <span class="n">expr3</span><span class="p">,</span> <span class="o">*</span><span class="n">expr4</span><span class="p">,</span> <span class="o">**</span><span class="n">expr5</span><span class="p">)</span>
<span class="n">expr3</span><span class="p">,</span> <span class="n">expr4</span> <span class="o">=</span> <span class="n">expr1</span><span class="p">,</span> <span class="n">expr2</span>
</pre></div>
</div>
</div>
<div class="section" id="operator-precedence">
<span id="operator-summary"></span><h2><span class="section-number">6.16. </span>运算符优先级<a class="headerlink" href="#operator-precedence" title="永久链接至标题">¶</a></h2>
<p id="index-92">下表对 Python 中运算符的优先顺序进行了总结，从最低优先级（最后绑定）到最高优先级（最先绑定）。 相同单元格内的运算符具有相同优先级。 除非句法显式地给出，否则运算符均指二元运算。 相同单元格内的运算符均从左至右分组（除了幂运算是从右至左分组）。</p>
<p>请注意比较、成员检测和标识号检测均为相同优先级，并具有如 <a class="reference internal" href="#comparisons"><span class="std std-ref">比较运算</span></a> 一节所描述的从左至右串连特性。</p>
<table class="docutils align-default">
<colgroup>
<col style="width: 56%" />
<col style="width: 44%" />
</colgroup>
<thead>
<tr class="row-odd"><th class="head"><p>运算符</p></th>
<th class="head"><p>描述</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p><a class="reference internal" href="#lambda"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">lambda</span></code></a></p></td>
<td><p>lambda 表达式</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#if-expr"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code></a> -- <code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code></p></td>
<td><p>条件表达式</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#or"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">or</span></code></a></p></td>
<td><p>布尔逻辑或 OR</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#and"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">and</span></code></a></p></td>
<td><p>布尔逻辑与 AND</p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#not"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">not</span></code></a> <code class="docutils literal notranslate"><span class="pre">x</span></code></p></td>
<td><p>布尔逻辑非 NOT</p></td>
</tr>
<tr class="row-odd"><td><p><a class="reference internal" href="#in"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">in</span></code></a>, <a class="reference internal" href="#not-in"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">not</span> <span class="pre">in</span></code></a>,
<a class="reference internal" href="#is"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">is</span></code></a>, <a class="reference internal" href="#is-not"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">is</span> <span class="pre">not</span></code></a>, <code class="docutils literal notranslate"><span class="pre">&lt;</span></code>,
<code class="docutils literal notranslate"><span class="pre">&lt;=</span></code>, <code class="docutils literal notranslate"><span class="pre">&gt;</span></code>, <code class="docutils literal notranslate"><span class="pre">&gt;=</span></code>, <code class="docutils literal notranslate"><span class="pre">!=</span></code>, <code class="docutils literal notranslate"><span class="pre">==</span></code></p></td>
<td><p>比较运算，包括成员检测和标识号检测</p></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">|</span></code></p></td>
<td><p>按位或 OR</p></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">^</span></code></p></td>
<td><p>按位异或 XOR</p></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">&amp;</span></code></p></td>
<td><p>按位与 AND</p></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">&lt;&lt;</span></code>, <code class="docutils literal notranslate"><span class="pre">&gt;&gt;</span></code></p></td>
<td><p>移位</p></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">+</span></code>, <code class="docutils literal notranslate"><span class="pre">-</span></code></p></td>
<td><p>加和减</p></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">*</span></code>, <code class="docutils literal notranslate"><span class="pre">&#64;</span></code>, <code class="docutils literal notranslate"><span class="pre">/</span></code>, <code class="docutils literal notranslate"><span class="pre">//</span></code>, <code class="docutils literal notranslate"><span class="pre">%</span></code></p></td>
<td><p>乘，矩阵乘，除，整除，取余 <a class="footnote-reference brackets" href="#id21" id="id15">5</a></p></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">+x</span></code>, <code class="docutils literal notranslate"><span class="pre">-x</span></code>, <code class="docutils literal notranslate"><span class="pre">~x</span></code></p></td>
<td><p>正，负，按位非 NOT</p></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">**</span></code></p></td>
<td><p>乘方 <a class="footnote-reference brackets" href="#id22" id="id16">6</a></p></td>
</tr>
<tr class="row-even"><td><p><a class="reference internal" href="#await"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">await</span></code></a> <code class="docutils literal notranslate"><span class="pre">x</span></code></p></td>
<td><p>await 表达式</p></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">x[index]</span></code>, <code class="docutils literal notranslate"><span class="pre">x[index:index]</span></code>,
<code class="docutils literal notranslate"><span class="pre">x(arguments...)</span></code>, <code class="docutils literal notranslate"><span class="pre">x.attribute</span></code></p></td>
<td><p>抽取，切片，调用，属性引用</p></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">(expressions...)</span></code>,</p>
<p><code class="docutils literal notranslate"><span class="pre">[expressions...]</span></code>,
<code class="docutils literal notranslate"><span class="pre">{key:</span> <span class="pre">value...}</span></code>,
<code class="docutils literal notranslate"><span class="pre">{expressions...}</span></code></p>
</td>
<td><p>绑定或加圆括号的表达式，列表显示，字典显示，集合显示</p></td>
</tr>
</tbody>
</table>
<p class="rubric">备注</p>
<dl class="footnote brackets">
<dt class="label" id="id17"><span class="brackets"><a class="fn-backref" href="#id9">1</a></span></dt>
<dd><p>虽然 <code class="docutils literal notranslate"><span class="pre">abs(x%y)</span> <span class="pre">&lt;</span> <span class="pre">abs(y)</span></code> 在数学中必为真，但对于浮点数而言，由于舍入的存在，其在数值上未必为真。 例如，假设在某个平台上的 Python 浮点数为一个 IEEE 754 双精度数值，为了使 <code class="docutils literal notranslate"><span class="pre">-1e-100</span> <span class="pre">%</span> <span class="pre">1e100</span></code> 具有与 <code class="docutils literal notranslate"><span class="pre">1e100</span></code> 相同的正负性，计算结果将是 <code class="docutils literal notranslate"><span class="pre">-1e-100</span> <span class="pre">+</span> <span class="pre">1e100</span></code>，这在数值上正好等于 <code class="docutils literal notranslate"><span class="pre">1e100</span></code>。 函数 <a class="reference internal" href="../library/math.html#math.fmod" title="math.fmod"><code class="xref py py-func docutils literal notranslate"><span class="pre">math.fmod()</span></code></a> 返回的结果则会具有与第一个参数相同的正负性，因此在这种情况下将返回 <code class="docutils literal notranslate"><span class="pre">-1e-100</span></code>。 何种方式更适宜取决于具体的应用。</p>
</dd>
<dt class="label" id="id18"><span class="brackets"><a class="fn-backref" href="#id10">2</a></span></dt>
<dd><p>如果 x 恰好非常接近于 y 的整数倍，则由于舍入的存在 <code class="docutils literal notranslate"><span class="pre">x//y</span></code> 可能会比 <code class="docutils literal notranslate"><span class="pre">(x-x%y)//y</span></code> 大。 在这种情况下，Python 会返回后一个结果，以便保持令 <code class="docutils literal notranslate"><span class="pre">divmod(x,y)[0]</span> <span class="pre">*</span> <span class="pre">y</span> <span class="pre">+</span> <span class="pre">x</span> <span class="pre">%</span> <span class="pre">y</span></code> 尽量接近 <code class="docutils literal notranslate"><span class="pre">x</span></code>.</p>
</dd>
<dt class="label" id="id19"><span class="brackets"><a class="fn-backref" href="#id12">3</a></span></dt>
<dd><p>Unicode 标准明确区分 <em class="dfn">码位</em> (例如 U+0041) 和 <em class="dfn">抽象字符</em> (例如 &quot;大写拉丁字母 A&quot;)。 虽然 Unicode 中的大多数抽象字符都只用一个码位来代表，但也存在一些抽象字符可使用由多个码位组成的序列来表示。 例如，抽象字符 &quot;带有下加符的大写拉丁字母 C&quot; 可以用 U+00C7 码位上的单个 <em class="dfn">预设字符</em> 来表示，也可以用一个 U+0043 码位上的 <em class="dfn">基础字符</em> (大写拉丁字母 C) 加上一个 U+0327 码位上的 <em class="dfn">组合字符</em> (组合下加符) 组成的序列来表示。</p>
<p>对于字符串，比较运算符会按 Unicode 码位级别进行比较。 这可能会违反人类的直觉。 例如，<code class="docutils literal notranslate"><span class="pre">&quot;\u00C7&quot;</span> <span class="pre">==</span> <span class="pre">&quot;\u0043\u0327&quot;</span></code> 为 <code class="docutils literal notranslate"><span class="pre">False</span></code>，虽然两个字符串都代表同一个抽象字符 &quot;带有下加符的大写拉丁字母 C&quot;。</p>
<p>要按抽象字符级别（即对人类来说更直观的方式）对字符串进行比较，应使用 <a class="reference internal" href="../library/unicodedata.html#unicodedata.normalize" title="unicodedata.normalize"><code class="xref py py-func docutils literal notranslate"><span class="pre">unicodedata.normalize()</span></code></a>。</p>
</dd>
<dt class="label" id="id20"><span class="brackets"><a class="fn-backref" href="#id13">4</a></span></dt>
<dd><p>由于存在自动垃圾收集、空闲列表以及描述器的动态特性，你可能会注意到在特定情况下使用 <a class="reference internal" href="#is"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">is</span></code></a> 运算符会出现看似不正常的行为，例如涉及到实例方法或常量之间的比较时就是如此。 更多信息请查看有关它们的文档。</p>
</dd>
<dt class="label" id="id21"><span class="brackets"><a class="fn-backref" href="#id15">5</a></span></dt>
<dd><p><code class="docutils literal notranslate"><span class="pre">%</span></code> 运算符也被用于字符串格式化；在此场合下会使用同样的优先级。</p>
</dd>
<dt class="label" id="id22"><span class="brackets"><a class="fn-backref" href="#id16">6</a></span></dt>
<dd><p>幂运算符 <code class="docutils literal notranslate"><span class="pre">**</span></code> 绑定的紧密程度低于在其右侧的算术或按位一元运算符，也就是说 <code class="docutils literal notranslate"><span class="pre">2**-1</span></code> 为 <code class="docutils literal notranslate"><span class="pre">0.5</span></code>。</p>
</dd>
</dl>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
        <div class="sphinxsidebarwrapper">
  <h3><a href="../contents.html">目录</a></h3>
  <ul>
<li><a class="reference internal" href="#">6. 表达式</a><ul>
<li><a class="reference internal" href="#arithmetic-conversions">6.1. 算术转换</a></li>
<li><a class="reference internal" href="#atoms">6.2. 原子</a><ul>
<li><a class="reference internal" href="#atom-identifiers">6.2.1. 标识符（名称）</a></li>
<li><a class="reference internal" href="#literals">6.2.2. 字面值</a></li>
<li><a class="reference internal" href="#parenthesized-forms">6.2.3. 带圆括号的形式</a></li>
<li><a class="reference internal" href="#displays-for-lists-sets-and-dictionaries">6.2.4. 列表、集合与字典的显示</a></li>
<li><a class="reference internal" href="#list-displays">6.2.5. 列表显示</a></li>
<li><a class="reference internal" href="#set-displays">6.2.6. 集合显示</a></li>
<li><a class="reference internal" href="#dictionary-displays">6.2.7. 字典显示</a></li>
<li><a class="reference internal" href="#generator-expressions">6.2.8. 生成器表达式</a></li>
<li><a class="reference internal" href="#yield-expressions">6.2.9. yield 表达式</a><ul>
<li><a class="reference internal" href="#generator-iterator-methods">6.2.9.1. 生成器-迭代器的方法</a></li>
<li><a class="reference internal" href="#examples">6.2.9.2. 例子</a></li>
<li><a class="reference internal" href="#asynchronous-generator-functions">6.2.9.3. 异步生成器函数</a></li>
<li><a class="reference internal" href="#asynchronous-generator-iterator-methods">6.2.9.4. 异步生成器-迭代器方法</a></li>
</ul>
</li>
</ul>
</li>
<li><a class="reference internal" href="#primaries">6.3. 原型</a><ul>
<li><a class="reference internal" href="#attribute-references">6.3.1. 属性引用</a></li>
<li><a class="reference internal" href="#subscriptions">6.3.2. 抽取</a></li>
<li><a class="reference internal" href="#slicings">6.3.3. 切片</a></li>
<li><a class="reference internal" href="#calls">6.3.4. 调用</a></li>
</ul>
</li>
<li><a class="reference internal" href="#await-expression">6.4. await 表达式</a></li>
<li><a class="reference internal" href="#the-power-operator">6.5. 幂运算符</a></li>
<li><a class="reference internal" href="#unary-arithmetic-and-bitwise-operations">6.6. 一元算术和位运算</a></li>
<li><a class="reference internal" href="#binary-arithmetic-operations">6.7. 二元算术运算符</a></li>
<li><a class="reference internal" href="#shifting-operations">6.8. 移位运算</a></li>
<li><a class="reference internal" href="#binary-bitwise-operations">6.9. 二元位运算</a></li>
<li><a class="reference internal" href="#comparisons">6.10. 比较运算</a><ul>
<li><a class="reference internal" href="#value-comparisons">6.10.1. 值比较</a></li>
<li><a class="reference internal" href="#membership-test-operations">6.10.2. 成员检测运算</a></li>
<li><a class="reference internal" href="#is-not">6.10.3. 标识号比较</a></li>
</ul>
</li>
<li><a class="reference internal" href="#boolean-operations">6.11. 布尔运算</a></li>
<li><a class="reference internal" href="#conditional-expressions">6.12. 条件表达式</a></li>
<li><a class="reference internal" href="#lambda">6.13. lambda 表达式</a></li>
<li><a class="reference internal" href="#expression-lists">6.14. 表达式列表</a></li>
<li><a class="reference internal" href="#evaluation-order">6.15. 求值顺序</a></li>
<li><a class="reference internal" href="#operator-precedence">6.16. 运算符优先级</a></li>
</ul>
</li>
</ul>

  <h4>上一个主题</h4>
  <p class="topless"><a href="import.html"
                        title="上一章"><span class="section-number">5. </span>导入系统</a></p>
  <h4>下一个主题</h4>
  <p class="topless"><a href="simple_stmts.html"
                        title="下一章"><span class="section-number">7. </span>简单语句</a></p>
  <div role="note" aria-label="source link">
    <h3>本页</h3>
    <ul class="this-page-menu">
      <li><a href="../bugs.html">提交 Bug</a></li>
      <li>
        <a href="https://github.com/python/cpython/blob/3.7/Doc/reference/expressions.rst"
            rel="nofollow">显示源代码
        </a>
      </li>
    </ul>
  </div>
        </div>
      </div>
      <div class="clearer"></div>
    </div>  
    <div class="related" role="navigation" aria-label="related navigation">
      <h3>导航</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../genindex.html" title="总目录"
             >索引</a></li>
        <li class="right" >
          <a href="../py-modindex.html" title="Python 模块索引"
             >模块</a> |</li>
        <li class="right" >
          <a href="simple_stmts.html" title="7. 简单语句"
             >下一页</a> |</li>
        <li class="right" >
          <a href="import.html" title="5. 导入系统"
             >上一页</a> |</li>
        <li><img src="../_static/py.png" alt=""
                 style="vertical-align: middle; margin-top: -1px"/></li>
        <li><a href="https://www.python.org/">Python</a> &#187;</li>
        <li>
          <a href="../index.html">3.7.8 Documentation</a> &#187;
        </li>

          <li class="nav-item nav-item-1"><a href="index.html" >Python语言参考</a> &#187;</li>
    <li class="right">
        

    <div class="inline-search" style="display: none" role="search">
        <form class="inline-search" action="../search.html" method="get">
          <input placeholder="快速搜索" type="text" name="q" />
          <input type="submit" value="转向" />
          <input type="hidden" name="check_keywords" value="yes" />
          <input type="hidden" name="area" value="default" />
        </form>
    </div>
    <script type="text/javascript">$('.inline-search').show(0);</script>
         |
    </li>

      </ul>
    </div>  
    <div class="footer">
    &copy; <a href="../copyright.html">版权所有</a> 2001-2020, Python Software Foundation.
    <br />
    Python 软件基金会是一个非盈利组织。
    <a href="https://www.python.org/psf/donations/">请捐助。</a>
    <br />
    最后更新于 6月 29, 2020.
    <a href="../bugs.html">发现了问题</a>？
    <br />
    使用<a href="http://sphinx.pocoo.org/">Sphinx</a>2.3.1 创建。
    </div>

  </body>
</html>